@hubspot/cli 6.1.1 → 6.2.1
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 +2 -2
- package/commands/accounts/clean.js +5 -7
- package/commands/auth.js +5 -5
- package/commands/cms/convertFields.js +2 -2
- package/commands/cms/lighthouseScore.js +47 -36
- package/commands/create/api-sample.js +2 -4
- package/commands/create/function.js +2 -2
- package/commands/create/module.js +2 -2
- package/commands/create/template.js +2 -2
- package/commands/create.js +3 -5
- package/commands/customObject/create.js +2 -2
- package/commands/customObject/schema/create.js +4 -4
- package/commands/customObject/schema/delete.js +2 -3
- package/commands/customObject/schema/fetch-all.js +2 -5
- package/commands/customObject/schema/fetch.js +2 -4
- package/commands/customObject/schema/list.js +2 -4
- package/commands/customObject/schema/update.js +4 -4
- package/commands/fetch.js +2 -2
- package/commands/filemanager/fetch.js +2 -2
- package/commands/filemanager/upload.js +3 -7
- package/commands/functions/deploy.js +26 -23
- package/commands/functions/list.js +3 -6
- package/commands/hubdb/clear.js +5 -3
- package/commands/hubdb/create.js +2 -2
- package/commands/hubdb/delete.js +2 -2
- package/commands/hubdb/fetch.js +2 -2
- package/commands/init.js +4 -7
- package/commands/lint.js +2 -2
- package/commands/list.js +4 -6
- package/commands/logs.js +6 -3
- package/commands/mv.js +3 -6
- package/commands/project/__tests__/deploy.test.js +37 -26
- package/commands/project/__tests__/logs.test.js +4 -5
- package/commands/project/add.js +2 -2
- package/commands/project/cloneApp.js +11 -9
- package/commands/project/create.js +2 -6
- package/commands/project/deploy.js +9 -12
- package/commands/project/dev.js +6 -5
- package/commands/project/download.js +7 -9
- package/commands/project/listBuilds.js +8 -12
- package/commands/project/logs.js +2 -2
- package/commands/project/migrateApp.js +20 -15
- package/commands/project/upload.js +4 -10
- package/commands/project/watch.js +8 -13
- package/commands/remove.js +2 -5
- package/commands/sandbox/create.js +4 -6
- package/commands/sandbox/delete.js +6 -12
- package/commands/secrets/addSecret.js +2 -5
- package/commands/secrets/deleteSecret.js +2 -5
- package/commands/secrets/listSecrets.js +5 -6
- package/commands/secrets/updateSecret.js +2 -5
- package/commands/theme/preview.js +2 -5
- package/commands/upload.js +3 -7
- package/commands/watch.js +3 -7
- package/lang/en.lyaml +14 -18
- package/lib/LocalDevManager.js +8 -6
- package/lib/__tests__/downloadProjectPrompt.test.js +1 -1
- package/lib/__tests__/projectLogsManager.test.js +19 -17
- package/lib/__tests__/serverlessLogs.test.js +13 -9
- package/lib/buildAccount.js +10 -10
- package/lib/developerTestAccounts.js +27 -27
- package/lib/errorHandlers/index.js +101 -0
- package/lib/errorHandlers/{overrideErrors.js → suppressError.js} +7 -7
- package/lib/hasFeature.js +15 -0
- package/lib/localDev.js +32 -19
- package/lib/marketplace-validate.js +3 -3
- package/lib/oauth.js +1 -1
- package/lib/polling.js +1 -1
- package/lib/projectLogsManager.js +3 -4
- package/lib/projectStructure.js +2 -2
- package/lib/projects.js +42 -29
- package/lib/projectsWatch.js +7 -12
- package/lib/prompts/createProjectPrompt.js +14 -5
- package/lib/prompts/downloadProjectPrompt.js +3 -6
- package/lib/prompts/projectDevTargetAccountPrompt.js +8 -6
- package/lib/prompts/selectPublicAppPrompt.js +5 -3
- package/lib/sandboxSync.js +7 -7
- package/lib/sandboxes.js +11 -7
- package/lib/schema.js +2 -2
- package/lib/serverlessLogs.js +67 -15
- package/lib/upload.js +2 -2
- package/lib/validation.js +2 -2
- package/package.json +8 -9
- package/lib/errorHandlers/apiErrors.js +0 -145
- package/lib/errorHandlers/fileSystemErrors.js +0 -20
- package/lib/errorHandlers/standardErrors.js +0 -103
|
@@ -14,7 +14,7 @@ const SLEEP_TIME = 2000;
|
|
|
14
14
|
const kickOffValidation = async (accountId, assetType, src) => {
|
|
15
15
|
const requestGroup = 'EXTERNAL_DEVELOPER';
|
|
16
16
|
try {
|
|
17
|
-
const requestResult = await requestValidation(accountId, {
|
|
17
|
+
const { data: requestResult } = await requestValidation(accountId, {
|
|
18
18
|
path: src,
|
|
19
19
|
assetType,
|
|
20
20
|
requestGroup,
|
|
@@ -29,7 +29,7 @@ const kickOffValidation = async (accountId, assetType, src) => {
|
|
|
29
29
|
const pollForValidationFinish = async (accountId, validationId) => {
|
|
30
30
|
try {
|
|
31
31
|
const checkValidationStatus = async () => {
|
|
32
|
-
const validationStatus = await getValidationStatus(accountId, {
|
|
32
|
+
const { data: validationStatus } = await getValidationStatus(accountId, {
|
|
33
33
|
validationId,
|
|
34
34
|
});
|
|
35
35
|
|
|
@@ -47,7 +47,7 @@ const pollForValidationFinish = async (accountId, validationId) => {
|
|
|
47
47
|
|
|
48
48
|
const fetchValidationResults = async (accountId, validationId) => {
|
|
49
49
|
try {
|
|
50
|
-
const validationResults = await getValidationResults(accountId, {
|
|
50
|
+
const { data: validationResults } = await getValidationResults(accountId, {
|
|
51
51
|
validationId,
|
|
52
52
|
});
|
|
53
53
|
return validationResults;
|
package/lib/oauth.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const open = require('open');
|
|
3
3
|
const {
|
|
4
|
-
|
|
4
|
+
OAuth2Manager,
|
|
5
5
|
} = require('@hubspot/local-dev-lib/models/OAuth2Manager');
|
|
6
6
|
const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
|
|
7
7
|
const { addOauthToAccountConfig } = require('@hubspot/local-dev-lib/oauth');
|
package/lib/polling.js
CHANGED
|
@@ -4,7 +4,7 @@ const poll = (callback, accountId, taskId) => {
|
|
|
4
4
|
return new Promise((resolve, reject) => {
|
|
5
5
|
const pollInterval = setInterval(async () => {
|
|
6
6
|
try {
|
|
7
|
-
const pollResp = await callback(accountId, taskId);
|
|
7
|
+
const { data: pollResp } = await callback(accountId, taskId);
|
|
8
8
|
const { status } = pollResp;
|
|
9
9
|
|
|
10
10
|
if (status === POLLING_STATUS.SUCCESS) {
|
|
@@ -54,10 +54,9 @@ class ProjectLogsManager {
|
|
|
54
54
|
throw new Error(i18n(`${i18nKey}.errors.noProjectConfig`));
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
const {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
);
|
|
57
|
+
const {
|
|
58
|
+
data: { topLevelComponentMetadata },
|
|
59
|
+
} = await fetchProjectComponentsMetadata(this.accountId, this.projectId);
|
|
61
60
|
|
|
62
61
|
const apps = topLevelComponentMetadata.filter(componentMetadata => {
|
|
63
62
|
const { type } = componentMetadata;
|
package/lib/projectStructure.js
CHANGED
|
@@ -2,7 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { walk } = require('@hubspot/local-dev-lib/fs');
|
|
4
4
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
5
|
-
const {
|
|
5
|
+
const { logError } = require('./errorHandlers/index');
|
|
6
6
|
|
|
7
7
|
const COMPONENT_TYPES = Object.freeze({
|
|
8
8
|
privateApp: 'private-app',
|
|
@@ -94,7 +94,7 @@ async function findProjectComponents(projectSourceDir) {
|
|
|
94
94
|
try {
|
|
95
95
|
projectFiles = await walk(projectSourceDir);
|
|
96
96
|
} catch (e) {
|
|
97
|
-
|
|
97
|
+
logError(e);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
projectFiles.forEach(projectFile => {
|
package/lib/projects.js
CHANGED
|
@@ -33,10 +33,7 @@ const {
|
|
|
33
33
|
fetchBuildWarnLogs,
|
|
34
34
|
fetchDeployWarnLogs,
|
|
35
35
|
} = require('@hubspot/local-dev-lib/api/projects');
|
|
36
|
-
const {
|
|
37
|
-
isSpecifiedError,
|
|
38
|
-
isSpecifiedHubSpotAuthError,
|
|
39
|
-
} = require('@hubspot/local-dev-lib/errors/apiErrors');
|
|
36
|
+
const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/index');
|
|
40
37
|
const { shouldIgnoreFile } = require('@hubspot/local-dev-lib/ignoreRules');
|
|
41
38
|
const { getCwd, getAbsoluteFilePath } = require('@hubspot/local-dev-lib/path');
|
|
42
39
|
const { downloadGithubRepoContents } = require('@hubspot/local-dev-lib/github');
|
|
@@ -45,10 +42,7 @@ const { EXIT_CODES } = require('./enums/exitCodes');
|
|
|
45
42
|
const { uiLine, uiLink, uiAccountDescription } = require('../lib/ui');
|
|
46
43
|
const { i18n } = require('./lang');
|
|
47
44
|
const SpinniesManager = require('./ui/SpinniesManager');
|
|
48
|
-
const {
|
|
49
|
-
logApiErrorInstance,
|
|
50
|
-
ApiErrorContext,
|
|
51
|
-
} = require('./errorHandlers/apiErrors');
|
|
45
|
+
const { logError, ApiErrorContext } = require('./errorHandlers/index');
|
|
52
46
|
|
|
53
47
|
const i18nKey = 'lib.projects';
|
|
54
48
|
|
|
@@ -215,11 +209,11 @@ const pollFetchProject = async (accountId, projectName) => {
|
|
|
215
209
|
});
|
|
216
210
|
const pollInterval = setInterval(async () => {
|
|
217
211
|
try {
|
|
218
|
-
const
|
|
219
|
-
if (
|
|
212
|
+
const response = await fetchProject(accountId, projectName);
|
|
213
|
+
if (response && response.data) {
|
|
220
214
|
SpinniesManager.remove('pollFetchProject');
|
|
221
215
|
clearInterval(pollInterval);
|
|
222
|
-
resolve(
|
|
216
|
+
resolve(response);
|
|
223
217
|
}
|
|
224
218
|
} catch (err) {
|
|
225
219
|
if (
|
|
@@ -254,7 +248,7 @@ const ensureProjectExists = async (
|
|
|
254
248
|
) => {
|
|
255
249
|
const accountIdentifier = uiAccountDescription(accountId);
|
|
256
250
|
try {
|
|
257
|
-
const project = withPolling
|
|
251
|
+
const { data: project } = withPolling
|
|
258
252
|
? await pollFetchProject(accountId, projectName)
|
|
259
253
|
: await fetchProject(accountId, projectName);
|
|
260
254
|
return { projectExists: !!project, project };
|
|
@@ -278,7 +272,7 @@ const ensureProjectExists = async (
|
|
|
278
272
|
|
|
279
273
|
if (shouldCreateProject) {
|
|
280
274
|
try {
|
|
281
|
-
const project = await createProject(accountId, projectName);
|
|
275
|
+
const { data: project } = await createProject(accountId, projectName);
|
|
282
276
|
logger.success(
|
|
283
277
|
i18n(`${i18nKey}.ensureProjectExists.createSuccess`, {
|
|
284
278
|
projectName,
|
|
@@ -287,7 +281,7 @@ const ensureProjectExists = async (
|
|
|
287
281
|
);
|
|
288
282
|
return { projectExists: true, project };
|
|
289
283
|
} catch (err) {
|
|
290
|
-
return
|
|
284
|
+
return logError(err, new ApiErrorContext({ accountId }));
|
|
291
285
|
}
|
|
292
286
|
} else {
|
|
293
287
|
if (!noLogs) {
|
|
@@ -302,14 +296,14 @@ const ensureProjectExists = async (
|
|
|
302
296
|
}
|
|
303
297
|
}
|
|
304
298
|
if (
|
|
305
|
-
|
|
299
|
+
isSpecifiedError(err, {
|
|
306
300
|
statusCode: 401,
|
|
307
301
|
})
|
|
308
302
|
) {
|
|
309
303
|
logger.error(err.message);
|
|
310
304
|
process.exit(EXIT_CODES.ERROR);
|
|
311
305
|
}
|
|
312
|
-
|
|
306
|
+
logError(err, new ApiErrorContext({ accountId }));
|
|
313
307
|
process.exit(EXIT_CODES.ERROR);
|
|
314
308
|
}
|
|
315
309
|
};
|
|
@@ -364,7 +358,7 @@ const uploadProjectFiles = async (
|
|
|
364
358
|
let error;
|
|
365
359
|
|
|
366
360
|
try {
|
|
367
|
-
const upload = await uploadProject(
|
|
361
|
+
const { data: upload } = await uploadProject(
|
|
368
362
|
accountId,
|
|
369
363
|
projectName,
|
|
370
364
|
filePath,
|
|
@@ -442,7 +436,7 @@ const pollProjectBuildAndDeploy = async (
|
|
|
442
436
|
)
|
|
443
437
|
);
|
|
444
438
|
|
|
445
|
-
displayWarnLogs(accountId, projectConfig.name, buildId);
|
|
439
|
+
await displayWarnLogs(accountId, projectConfig.name, buildId);
|
|
446
440
|
}
|
|
447
441
|
|
|
448
442
|
// autoDeployId of 0 indicates a skipped deploy
|
|
@@ -501,7 +495,7 @@ const pollProjectBuildAndDeploy = async (
|
|
|
501
495
|
}
|
|
502
496
|
|
|
503
497
|
if (result && result.deployResult) {
|
|
504
|
-
displayWarnLogs(
|
|
498
|
+
await displayWarnLogs(
|
|
505
499
|
accountId,
|
|
506
500
|
projectConfig.name,
|
|
507
501
|
result.deployResult.deployId,
|
|
@@ -636,8 +630,10 @@ const makePollTaskStatusFunc = ({
|
|
|
636
630
|
});
|
|
637
631
|
|
|
638
632
|
const [
|
|
639
|
-
initialTaskStatus,
|
|
640
|
-
{
|
|
633
|
+
{ data: initialTaskStatus },
|
|
634
|
+
{
|
|
635
|
+
data: { topLevelComponentsWithChildren: taskStructure },
|
|
636
|
+
},
|
|
641
637
|
] = await Promise.all([
|
|
642
638
|
statusFn(accountId, taskName, taskId),
|
|
643
639
|
structureFn(accountId, taskName, taskId),
|
|
@@ -711,9 +707,17 @@ const makePollTaskStatusFunc = ({
|
|
|
711
707
|
const pollInterval = setInterval(async () => {
|
|
712
708
|
let taskStatus;
|
|
713
709
|
try {
|
|
714
|
-
|
|
710
|
+
const { data } = await statusFn(accountId, taskName, taskId);
|
|
711
|
+
taskStatus = data;
|
|
715
712
|
} catch (e) {
|
|
716
713
|
logger.debug(e);
|
|
714
|
+
logError(
|
|
715
|
+
e,
|
|
716
|
+
new ApiErrorContext({
|
|
717
|
+
accountId,
|
|
718
|
+
projectName: taskName,
|
|
719
|
+
})
|
|
720
|
+
);
|
|
717
721
|
return reject(
|
|
718
722
|
new Error(
|
|
719
723
|
i18n(
|
|
@@ -981,22 +985,31 @@ const displayWarnLogs = async (
|
|
|
981
985
|
|
|
982
986
|
if (isDeploy) {
|
|
983
987
|
try {
|
|
984
|
-
|
|
988
|
+
const { data } = await fetchDeployWarnLogs(
|
|
989
|
+
accountId,
|
|
990
|
+
projectName,
|
|
991
|
+
taskId
|
|
992
|
+
);
|
|
993
|
+
result = data;
|
|
985
994
|
} catch (e) {
|
|
986
|
-
|
|
995
|
+
logError(e);
|
|
987
996
|
}
|
|
988
997
|
} else {
|
|
989
998
|
try {
|
|
990
|
-
|
|
999
|
+
const { data } = await fetchBuildWarnLogs(accountId, projectName, taskId);
|
|
1000
|
+
result = data;
|
|
991
1001
|
} catch (e) {
|
|
992
|
-
|
|
1002
|
+
logError(e);
|
|
993
1003
|
}
|
|
994
1004
|
}
|
|
995
1005
|
|
|
996
|
-
if (result && result.logs
|
|
997
|
-
result.logs.
|
|
1006
|
+
if (result && result.logs) {
|
|
1007
|
+
const logLength = result.logs.length;
|
|
1008
|
+
result.logs.forEach((log, i) => {
|
|
998
1009
|
logger.warn(log.message);
|
|
999
|
-
|
|
1010
|
+
if (i < logLength - 1) {
|
|
1011
|
+
logger.log('');
|
|
1012
|
+
}
|
|
1000
1013
|
});
|
|
1001
1014
|
}
|
|
1002
1015
|
};
|
package/lib/projectsWatch.js
CHANGED
|
@@ -2,10 +2,7 @@ const chokidar = require('chokidar');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const { default: PQueue } = require('p-queue');
|
|
5
|
-
const {
|
|
6
|
-
logApiErrorInstance,
|
|
7
|
-
ApiErrorContext,
|
|
8
|
-
} = require('./errorHandlers/apiErrors');
|
|
5
|
+
const { logError, ApiErrorContext } = require('./errorHandlers/index');
|
|
9
6
|
const { i18n } = require('./lang');
|
|
10
7
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
11
8
|
const { isAllowedExtension } = require('@hubspot/local-dev-lib/path');
|
|
@@ -17,7 +14,7 @@ const {
|
|
|
17
14
|
deleteFileFromBuild,
|
|
18
15
|
queueBuild,
|
|
19
16
|
} = require('@hubspot/local-dev-lib/api/projects');
|
|
20
|
-
const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/
|
|
17
|
+
const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/index');
|
|
21
18
|
const { PROJECT_ERROR_TYPES } = require('./constants');
|
|
22
19
|
|
|
23
20
|
const i18nKey = 'commands.project.subcommands.watch';
|
|
@@ -85,7 +82,7 @@ const debounceQueueBuild = (accountId, projectName, platformVersion) => {
|
|
|
85
82
|
logger.log(i18n(`${i18nKey}.logs.watchCancelledFromUi`));
|
|
86
83
|
process.exit(0);
|
|
87
84
|
} else {
|
|
88
|
-
|
|
85
|
+
logError(err, new ApiErrorContext({ accountId }));
|
|
89
86
|
}
|
|
90
87
|
|
|
91
88
|
return;
|
|
@@ -148,14 +145,12 @@ const queueFileOrFolder = async (
|
|
|
148
145
|
const createNewBuild = async (accountId, projectName, platformVersion) => {
|
|
149
146
|
try {
|
|
150
147
|
logger.debug(i18n(`${i18nKey}.debug.attemptNewBuild`));
|
|
151
|
-
const {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
platformVersion
|
|
155
|
-
);
|
|
148
|
+
const {
|
|
149
|
+
data: { buildId },
|
|
150
|
+
} = await provisionBuild(accountId, projectName, platformVersion);
|
|
156
151
|
return buildId;
|
|
157
152
|
} catch (err) {
|
|
158
|
-
|
|
153
|
+
logError(err, new ApiErrorContext({ accountId }));
|
|
159
154
|
if (
|
|
160
155
|
isSpecifiedError(err, { subCategory: PROJECT_ERROR_TYPES.PROJECT_LOCKED })
|
|
161
156
|
) {
|
|
@@ -60,14 +60,20 @@ const createProjectPrompt = async (
|
|
|
60
60
|
skipTemplatePrompt = false
|
|
61
61
|
) => {
|
|
62
62
|
let projectTemplates = [];
|
|
63
|
+
let selectedTemplate;
|
|
64
|
+
|
|
63
65
|
if (!skipTemplatePrompt) {
|
|
64
66
|
projectTemplates = await createTemplateOptions(
|
|
65
67
|
promptOptions.templateSource,
|
|
66
68
|
githubRef
|
|
67
69
|
);
|
|
70
|
+
|
|
71
|
+
selectedTemplate =
|
|
72
|
+
promptOptions.template &&
|
|
73
|
+
projectTemplates.find(t => t.name === promptOptions.template);
|
|
68
74
|
}
|
|
69
75
|
|
|
70
|
-
|
|
76
|
+
const result = await promptUser([
|
|
71
77
|
{
|
|
72
78
|
name: 'name',
|
|
73
79
|
message: i18n(`${i18nKey}.enterName`),
|
|
@@ -115,10 +121,7 @@ const createProjectPrompt = async (
|
|
|
115
121
|
})
|
|
116
122
|
: i18n(`${i18nKey}.selectTemplate`);
|
|
117
123
|
},
|
|
118
|
-
when:
|
|
119
|
-
!skipTemplatePrompt &&
|
|
120
|
-
(!promptOptions.template ||
|
|
121
|
-
!projectTemplates.find(t => t.name === promptOptions.template)),
|
|
124
|
+
when: !skipTemplatePrompt && !selectedTemplate,
|
|
122
125
|
type: 'list',
|
|
123
126
|
choices: projectTemplates.map(template => {
|
|
124
127
|
return {
|
|
@@ -128,6 +131,12 @@ const createProjectPrompt = async (
|
|
|
128
131
|
}),
|
|
129
132
|
},
|
|
130
133
|
]);
|
|
134
|
+
|
|
135
|
+
if (selectedTemplate) {
|
|
136
|
+
result.template = selectedTemplate;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return result;
|
|
131
140
|
};
|
|
132
141
|
|
|
133
142
|
module.exports = {
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
const { promptUser } = require('./promptUtils');
|
|
2
2
|
const { getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
3
3
|
const { fetchProjects } = require('@hubspot/local-dev-lib/api/projects');
|
|
4
|
-
const {
|
|
5
|
-
logApiErrorInstance,
|
|
6
|
-
ApiErrorContext,
|
|
7
|
-
} = require('../../lib/errorHandlers/apiErrors');
|
|
4
|
+
const { logError, ApiErrorContext } = require('../../lib/errorHandlers/index');
|
|
8
5
|
const { EXIT_CODES } = require('../enums/exitCodes');
|
|
9
6
|
const { i18n } = require('../lang');
|
|
10
7
|
|
|
@@ -12,10 +9,10 @@ const i18nKey = 'lib.prompts.downloadProjectPrompt';
|
|
|
12
9
|
|
|
13
10
|
const createProjectsList = async accountId => {
|
|
14
11
|
try {
|
|
15
|
-
const projects = await fetchProjects(accountId);
|
|
12
|
+
const { data: projects } = await fetchProjects(accountId);
|
|
16
13
|
return projects.results;
|
|
17
14
|
} catch (e) {
|
|
18
|
-
|
|
15
|
+
logError(e, new ApiErrorContext({ accountId }));
|
|
19
16
|
process.exit(EXIT_CODES.ERROR);
|
|
20
17
|
}
|
|
21
18
|
};
|
|
@@ -3,7 +3,9 @@ const { i18n } = require('../lang');
|
|
|
3
3
|
const { uiAccountDescription, uiCommandReference } = require('../ui');
|
|
4
4
|
const { isSandbox } = require('../accountTypes');
|
|
5
5
|
const { getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
6
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
getSandboxUsageLimits,
|
|
8
|
+
} = require('@hubspot/local-dev-lib/api/sandboxHubs');
|
|
7
9
|
const {
|
|
8
10
|
HUBSPOT_ACCOUNT_TYPES,
|
|
9
11
|
HUBSPOT_ACCOUNT_TYPE_STRINGS,
|
|
@@ -11,7 +13,7 @@ const {
|
|
|
11
13
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
12
14
|
const {
|
|
13
15
|
fetchDeveloperTestAccounts,
|
|
14
|
-
} = require('@hubspot/local-dev-lib/developerTestAccounts');
|
|
16
|
+
} = require('@hubspot/local-dev-lib/api/developerTestAccounts');
|
|
15
17
|
|
|
16
18
|
const i18nKey = 'lib.prompts.projectDevTargetAccountPrompt';
|
|
17
19
|
|
|
@@ -38,7 +40,8 @@ const selectSandboxTargetAccountPrompt = async (
|
|
|
38
40
|
let choices = [];
|
|
39
41
|
let sandboxUsage = {};
|
|
40
42
|
try {
|
|
41
|
-
|
|
43
|
+
const { data } = await getSandboxUsageLimits(defaultAccountId);
|
|
44
|
+
sandboxUsage = data.usage;
|
|
42
45
|
} catch (err) {
|
|
43
46
|
logger.debug('Unable to fetch sandbox usage limits: ', err);
|
|
44
47
|
}
|
|
@@ -101,9 +104,8 @@ const selectDeveloperTestTargetAccountPrompt = async (
|
|
|
101
104
|
const defaultAccountId = getAccountId(defaultAccountConfig.name);
|
|
102
105
|
let devTestAccountsResponse = undefined;
|
|
103
106
|
try {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
);
|
|
107
|
+
const { data } = await fetchDeveloperTestAccounts(defaultAccountId);
|
|
108
|
+
devTestAccountsResponse = data;
|
|
107
109
|
} catch (err) {
|
|
108
110
|
logger.debug('Unable to fetch developer test account usage limits: ', err);
|
|
109
111
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { promptUser } = require('./promptUtils');
|
|
2
2
|
const { i18n } = require('../lang');
|
|
3
3
|
const { uiLine } = require('../ui');
|
|
4
|
-
const {
|
|
4
|
+
const { logError } = require('../errorHandlers/index');
|
|
5
5
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
6
6
|
const {
|
|
7
7
|
fetchPublicAppsForPortal,
|
|
@@ -16,7 +16,9 @@ const fetchPublicAppOptions = async (
|
|
|
16
16
|
isMigratingApp = false
|
|
17
17
|
) => {
|
|
18
18
|
try {
|
|
19
|
-
const
|
|
19
|
+
const {
|
|
20
|
+
data: { results: publicApps },
|
|
21
|
+
} = await fetchPublicAppsForPortal(accountId);
|
|
20
22
|
const filteredPublicApps = publicApps.filter(
|
|
21
23
|
app => !app.projectId && !app.sourceId
|
|
22
24
|
);
|
|
@@ -44,7 +46,7 @@ const fetchPublicAppOptions = async (
|
|
|
44
46
|
}
|
|
45
47
|
return filteredPublicApps;
|
|
46
48
|
} catch (error) {
|
|
47
|
-
|
|
49
|
+
logError(error, { accountId });
|
|
48
50
|
logger.error(i18n(`${i18nKey}.errors.errorFetchingApps`));
|
|
49
51
|
process.exit(EXIT_CODES.ERROR);
|
|
50
52
|
}
|
package/lib/sandboxSync.js
CHANGED
|
@@ -3,13 +3,13 @@ const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
|
3
3
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
4
4
|
const { i18n } = require('./lang');
|
|
5
5
|
const { getAvailableSyncTypes } = require('./sandboxes');
|
|
6
|
-
const { initiateSync } = require('@hubspot/local-dev-lib/
|
|
7
|
-
const { debugErrorAndContext } = require('./errorHandlers/standardErrors');
|
|
6
|
+
const { initiateSync } = require('@hubspot/local-dev-lib/api/sandboxSync');
|
|
8
7
|
const {
|
|
9
|
-
|
|
8
|
+
debugError,
|
|
9
|
+
logError,
|
|
10
10
|
ApiErrorContext,
|
|
11
|
-
} = require('./errorHandlers/
|
|
12
|
-
const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/
|
|
11
|
+
} = require('./errorHandlers/index');
|
|
12
|
+
const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/index');
|
|
13
13
|
const { getSandboxTypeAsString } = require('./sandboxes');
|
|
14
14
|
const { getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
15
15
|
const {
|
|
@@ -88,7 +88,7 @@ const syncSandbox = async ({
|
|
|
88
88
|
),
|
|
89
89
|
});
|
|
90
90
|
} catch (err) {
|
|
91
|
-
|
|
91
|
+
debugError(err);
|
|
92
92
|
|
|
93
93
|
SpinniesManager.fail('sandboxSync', {
|
|
94
94
|
text: i18n(`${i18nKey}.loading.fail`),
|
|
@@ -155,7 +155,7 @@ const syncSandbox = async ({
|
|
|
155
155
|
'https://app.hubspot.com/l/docs/guides/crm/project-cli-commands#developer-projects-cli-commands-beta'
|
|
156
156
|
);
|
|
157
157
|
} else {
|
|
158
|
-
|
|
158
|
+
logError(
|
|
159
159
|
err,
|
|
160
160
|
new ApiErrorContext({
|
|
161
161
|
accountId: parentAccountId,
|
package/lib/sandboxes.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const { i18n } = require('./lang');
|
|
2
2
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
3
3
|
const {
|
|
4
|
-
fetchTypes,
|
|
5
4
|
getSandboxUsageLimits,
|
|
6
|
-
} = require('@hubspot/local-dev-lib/
|
|
5
|
+
} = require('@hubspot/local-dev-lib/api/sandboxHubs');
|
|
6
|
+
const { fetchTypes } = require('@hubspot/local-dev-lib/api/sandboxSync');
|
|
7
7
|
const {
|
|
8
8
|
getConfig,
|
|
9
9
|
getAccountId,
|
|
@@ -19,9 +19,9 @@ const { uiAccountDescription } = require('./ui');
|
|
|
19
19
|
const {
|
|
20
20
|
isMissingScopeError,
|
|
21
21
|
isSpecifiedError,
|
|
22
|
-
} = require('@hubspot/local-dev-lib/errors/
|
|
22
|
+
} = require('@hubspot/local-dev-lib/errors/index');
|
|
23
23
|
const { getValidEnv } = require('@hubspot/local-dev-lib/environment');
|
|
24
|
-
const {
|
|
24
|
+
const { logError } = require('./errorHandlers/index');
|
|
25
25
|
|
|
26
26
|
const syncTypes = {
|
|
27
27
|
OBJECT_RECORDS: 'object-records',
|
|
@@ -73,7 +73,9 @@ function getSandboxLimit(error) {
|
|
|
73
73
|
async function getAvailableSyncTypes(parentAccountConfig, config) {
|
|
74
74
|
const parentPortalId = getAccountId(parentAccountConfig.portalId);
|
|
75
75
|
const portalId = getAccountId(config.portalId);
|
|
76
|
-
const
|
|
76
|
+
const {
|
|
77
|
+
data: { results: syncTypes },
|
|
78
|
+
} = await fetchTypes(parentPortalId, portalId);
|
|
77
79
|
if (!syncTypes) {
|
|
78
80
|
throw new Error(
|
|
79
81
|
'Unable to fetch available sandbox sync types. Please try again.'
|
|
@@ -126,7 +128,9 @@ const getSyncTypesWithContactRecordsPrompt = async (
|
|
|
126
128
|
*/
|
|
127
129
|
const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
128
130
|
const accountId = getAccountId(accountConfig.portalId);
|
|
129
|
-
const
|
|
131
|
+
const {
|
|
132
|
+
data: { usage },
|
|
133
|
+
} = await getSandboxUsageLimits(accountId);
|
|
130
134
|
if (!usage) {
|
|
131
135
|
throw new Error('Unable to fetch sandbox usage limits. Please try again.');
|
|
132
136
|
}
|
|
@@ -348,7 +352,7 @@ function handleSandboxCreateError({
|
|
|
348
352
|
}
|
|
349
353
|
logger.log('');
|
|
350
354
|
} else {
|
|
351
|
-
|
|
355
|
+
logError(err);
|
|
352
356
|
}
|
|
353
357
|
throw err;
|
|
354
358
|
}
|
package/lib/schema.js
CHANGED
|
@@ -24,8 +24,8 @@ const logSchemas = schemas => {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const listSchemas = async accountId => {
|
|
27
|
-
const
|
|
28
|
-
logSchemas(
|
|
27
|
+
const { data } = await fetchObjectSchemas(accountId);
|
|
28
|
+
logSchemas(data.results);
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
module.exports = {
|
package/lib/serverlessLogs.js
CHANGED
|
@@ -4,13 +4,20 @@ const { handleExit, handleKeypress } = require('./process');
|
|
|
4
4
|
const chalk = require('chalk');
|
|
5
5
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
6
6
|
const { outputLogs } = require('./ui/serverlessFunctionLogs');
|
|
7
|
-
const {
|
|
8
|
-
logServerlessFunctionApiErrorInstance,
|
|
9
|
-
logApiErrorInstance,
|
|
10
|
-
ApiErrorContext,
|
|
11
|
-
} = require('./errorHandlers/apiErrors');
|
|
7
|
+
const { logError, ApiErrorContext } = require('./errorHandlers/index');
|
|
12
8
|
|
|
13
9
|
const { EXIT_CODES } = require('../lib/enums/exitCodes');
|
|
10
|
+
const {
|
|
11
|
+
isHubSpotHttpError,
|
|
12
|
+
isMissingScopeError,
|
|
13
|
+
} = require('@hubspot/local-dev-lib/errors/index');
|
|
14
|
+
const {
|
|
15
|
+
SCOPE_GROUPS,
|
|
16
|
+
PERSONAL_ACCESS_KEY_AUTH_METHOD,
|
|
17
|
+
} = require('@hubspot/local-dev-lib/constants/auth');
|
|
18
|
+
const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
|
|
19
|
+
const { fetchScopeData } = require('@hubspot/local-dev-lib/api/localDevAuth');
|
|
20
|
+
const { i18n } = require('./lang');
|
|
14
21
|
|
|
15
22
|
const TAIL_DELAY = 5000;
|
|
16
23
|
|
|
@@ -38,6 +45,47 @@ const handleUserInput = () => {
|
|
|
38
45
|
});
|
|
39
46
|
};
|
|
40
47
|
|
|
48
|
+
async function verifyAccessKeyAndUserAccess(accountId, scopeGroup) {
|
|
49
|
+
const accountConfig = getAccountConfig(accountId);
|
|
50
|
+
// TODO[JOE]: Update this i18n key
|
|
51
|
+
const i18nKey = 'lib.serverless';
|
|
52
|
+
const { authType } = accountConfig;
|
|
53
|
+
if (authType !== PERSONAL_ACCESS_KEY_AUTH_METHOD.value) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let scopesData;
|
|
58
|
+
try {
|
|
59
|
+
scopesData = await fetchScopeData(accountId, scopeGroup);
|
|
60
|
+
} catch (e) {
|
|
61
|
+
logger.debug(
|
|
62
|
+
i18n(`${i18nKey}.verifyAccessKeyAndUserAccess.fetchScopeDataError`, {
|
|
63
|
+
scopeGroup,
|
|
64
|
+
error: e,
|
|
65
|
+
})
|
|
66
|
+
);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const { portalScopesInGroup, userScopesInGroup } = scopesData;
|
|
70
|
+
|
|
71
|
+
if (!portalScopesInGroup.length) {
|
|
72
|
+
logger.error(
|
|
73
|
+
i18n(`${i18nKey}.verifyAccessKeyAndUserAccess.portalMissingScope`)
|
|
74
|
+
);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!portalScopesInGroup.every(s => userScopesInGroup.includes(s))) {
|
|
79
|
+
logger.error(
|
|
80
|
+
i18n(`${i18nKey}.verifyAccessKeyAndUserAccess.userMissingScope`)
|
|
81
|
+
);
|
|
82
|
+
} else {
|
|
83
|
+
logger.error(
|
|
84
|
+
i18n(`${i18nKey}.verifyAccessKeyAndUserAccess.genericMissingScope`)
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
41
89
|
const tailLogs = async ({
|
|
42
90
|
accountId,
|
|
43
91
|
compact,
|
|
@@ -48,16 +96,19 @@ const tailLogs = async ({
|
|
|
48
96
|
let initialAfter;
|
|
49
97
|
|
|
50
98
|
try {
|
|
51
|
-
const latestLog = await fetchLatest();
|
|
99
|
+
const { data: latestLog } = await fetchLatest();
|
|
52
100
|
initialAfter = latestLog && base64EncodeString(latestLog.id);
|
|
53
101
|
} catch (e) {
|
|
54
102
|
// A 404 means no latest log exists(never executed)
|
|
55
|
-
if (e
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
103
|
+
if (isHubSpotHttpError(e) && e.status !== 404) {
|
|
104
|
+
if (isMissingScopeError(e)) {
|
|
105
|
+
await verifyAccessKeyAndUserAccess(
|
|
106
|
+
accountId,
|
|
107
|
+
SCOPE_GROUPS.CMS_FUNCTIONS
|
|
108
|
+
);
|
|
109
|
+
} else {
|
|
110
|
+
await logError(e, new ApiErrorContext({ accountId }));
|
|
111
|
+
}
|
|
61
112
|
}
|
|
62
113
|
}
|
|
63
114
|
|
|
@@ -65,11 +116,12 @@ const tailLogs = async ({
|
|
|
65
116
|
let latestLog;
|
|
66
117
|
let nextAfter;
|
|
67
118
|
try {
|
|
68
|
-
|
|
119
|
+
const { data } = await tailCall(after);
|
|
120
|
+
latestLog = data;
|
|
69
121
|
nextAfter = latestLog.paging.next.after;
|
|
70
122
|
} catch (e) {
|
|
71
|
-
if (e
|
|
72
|
-
|
|
123
|
+
if (isHubSpotHttpError(e) && e.status !== 404) {
|
|
124
|
+
logError(
|
|
73
125
|
e,
|
|
74
126
|
new ApiErrorContext({
|
|
75
127
|
accountId,
|