@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
package/lang/en.lyaml
CHANGED
|
@@ -183,8 +183,6 @@ en:
|
|
|
183
183
|
noSamples: "Currently there are no samples available, please, try again later."
|
|
184
184
|
info:
|
|
185
185
|
sampleChosen: "You've chosen {{ sampleType }} sample written on {{ sampleLanguage }} language"
|
|
186
|
-
loading:
|
|
187
|
-
apiSamples: "Loading available API samples"
|
|
188
186
|
success:
|
|
189
187
|
sampleCreated: "Please, follow {{ filePath }}/README.md to find out how to run the sample"
|
|
190
188
|
module:
|
|
@@ -335,7 +333,8 @@ en:
|
|
|
335
333
|
notFunctionsFolder: "Specified path {{ functionPath }} is not a .functions folder."
|
|
336
334
|
examples:
|
|
337
335
|
default: "Build and deploy a new bundle for all functions within the myFunctionFolder.functions folder"
|
|
338
|
-
loading: "Building and deploying bundle for \"{{ functionPath }}\" on
|
|
336
|
+
loading: "Building and deploying bundle for \"{{ functionPath }}\" on {{ account }}"
|
|
337
|
+
loadingFailed: "Failed to build and deploy bundle for \"{{ functionPath }}\" on {{ account }}"
|
|
339
338
|
positionals:
|
|
340
339
|
path:
|
|
341
340
|
describe: "Path to .functions folder"
|
|
@@ -1008,7 +1007,9 @@ en:
|
|
|
1008
1007
|
localDev:
|
|
1009
1008
|
confirmDefaultAccountIsTarget:
|
|
1010
1009
|
declineDefaultAccountExplanation: "To develop on a different account, run {{ useCommand }} to change your default account, then re-run {{ devCommand }}."
|
|
1011
|
-
|
|
1010
|
+
checkIfDefaultAccountIsSupported:
|
|
1011
|
+
publicApp: "This project contains a public app. Local development of public apps is only supported on developer accounts and developer test accounts. Change your default account using {{ useCommand }}, or link a new account with {{ authCommand }}."
|
|
1012
|
+
privateApp: "This project contains a private app. Local development of private apps is not supported in developer accounts. Change your default account using {{ useCommand }}, or link a new account with {{ authCommand }}."
|
|
1012
1013
|
validateAccountOption:
|
|
1013
1014
|
invalidPublicAppAccount: "This project contains a public app. The \"--account\" flag must point to a developer test account to develop this project locally. Alternatively, change your default account to an App Developer Account using {{ useCommand }} and run {{ devCommand }} to set up a new Developer Test Account."
|
|
1014
1015
|
invalidPrivateAppAccount: "This project contains a private app. The account specified with the \"--account\" flag points to a developer account, which do not support the local development of private apps. Update the \"--account\" flag to point to a standard, sandbox, or developer test account, or change your default account by running {{ useCommand }}."
|
|
@@ -1401,23 +1402,12 @@ en:
|
|
|
1401
1402
|
notSuperAdmin: "Couldn't run the sync because you are not a super admin in {{ account }}. Ask the account owner for super admin access to the sandbox."
|
|
1402
1403
|
objectNotFound: "Couldn't sync the sandbox because {{#bold}}{{ account }}{{/bold}} may have been deleted through the UI. Run {{#bold}}hs sandbox delete{{/bold}} to remove this account from the config. "
|
|
1403
1404
|
errorHandlers:
|
|
1404
|
-
|
|
1405
|
+
index:
|
|
1405
1406
|
errorOccurred: "Error: {{ error }}"
|
|
1406
1407
|
errorContext: "Context: {{ context }}"
|
|
1407
1408
|
errorCause: "Cause: {{ cause }}"
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
unknownErrorOccurred: "An unknown error has occurred"
|
|
1411
|
-
fileSystemErrors:
|
|
1412
|
-
errorOccurred: "An error occurred while {{ fileAction }} {{ filepath }}."
|
|
1413
|
-
errorExplanation: "This is the result of a system error: {{ errorMessage }}"
|
|
1414
|
-
apiErrors:
|
|
1415
|
-
verifyAccessKeyAndUserAccess:
|
|
1416
|
-
fetchScopeDataError: "Error verifying access of scopeGroup {{ scopeGroup }}: {{ error }}"
|
|
1417
|
-
portalMissingScope: "Your account does not have access to this action. Talk to an account admin to request it."
|
|
1418
|
-
userMissingScope: "You don't have access to this action. Ask an account admin to change your permissions in Users & Teams settings."
|
|
1419
|
-
genericMissingScope: "Your access key does not allow this action. Please generate a new access key by running `hs auth personalaccesskey`."
|
|
1420
|
-
overrideErrors:
|
|
1409
|
+
unknownErrorOccurred: "An unknown error has occurred."
|
|
1410
|
+
suppressErrors:
|
|
1421
1411
|
platformVersionErrors:
|
|
1422
1412
|
header: "Platform version update required"
|
|
1423
1413
|
unspecifiedPlatformVersion: "Projects with an {{#bold}}{{platformVersion}}{{/bold}} are no longer supported."
|
|
@@ -1427,3 +1417,9 @@ en:
|
|
|
1427
1417
|
docsLink: "Projects platform versioning (BETA)"
|
|
1428
1418
|
betaLink: "For more info, see {{ docsLink }}."
|
|
1429
1419
|
missingScopeError: "Couldn't execute the {{ request }} because the access key for {{ accountName }} is missing required scopes. To update scopes, run {{ authCommand }}. Then deactivate the existing key and generate a new one that includes the missing scopes."
|
|
1420
|
+
serverless:
|
|
1421
|
+
verifyAccessKeyAndUserAccess:
|
|
1422
|
+
fetchScopeDataError: "Error verifying access of scopeGroup {{ scopeGroup }}: {{ error }}"
|
|
1423
|
+
portalMissingScope: "Your account does not have access to this action. Talk to an account admin to request it."
|
|
1424
|
+
userMissingScope: "You don't have access to this action. Ask an account admin to change your permissions in Users & Teams settings."
|
|
1425
|
+
genericMissingScope: "Your access key does not allow this action. Please generate a new access key by running `hs auth personalaccesskey`."
|
package/lib/LocalDevManager.js
CHANGED
|
@@ -34,7 +34,7 @@ const {
|
|
|
34
34
|
uiLink,
|
|
35
35
|
uiLine,
|
|
36
36
|
} = require('./ui');
|
|
37
|
-
const {
|
|
37
|
+
const { logError } = require('./errorHandlers/index');
|
|
38
38
|
const { installPublicAppPrompt } = require('./prompts/installPublicAppPrompt');
|
|
39
39
|
const {
|
|
40
40
|
activeInstallConfirmationPrompt,
|
|
@@ -99,7 +99,7 @@ class LocalDevManager {
|
|
|
99
99
|
await this.checkActivePublicAppInstalls();
|
|
100
100
|
await this.checkPublicAppInstallation();
|
|
101
101
|
} catch (e) {
|
|
102
|
-
|
|
102
|
+
logError(e);
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
}
|
|
@@ -109,7 +109,7 @@ class LocalDevManager {
|
|
|
109
109
|
return;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
const portalPublicApps = await fetchPublicAppsForPortal(
|
|
112
|
+
const { data: portalPublicApps } = await fetchPublicAppsForPortal(
|
|
113
113
|
this.targetProjectAccountId
|
|
114
114
|
);
|
|
115
115
|
|
|
@@ -119,7 +119,7 @@ class LocalDevManager {
|
|
|
119
119
|
|
|
120
120
|
// TODO: Update to account for new API with { data }
|
|
121
121
|
const {
|
|
122
|
-
uniquePortalInstallCount,
|
|
122
|
+
data: { uniquePortalInstallCount },
|
|
123
123
|
} = await fetchPublicAppProductionInstallCounts(
|
|
124
124
|
activePublicAppData.id,
|
|
125
125
|
this.targetProjectAccountId
|
|
@@ -264,14 +264,16 @@ class LocalDevManager {
|
|
|
264
264
|
process.exit(EXIT_CODES.SUCCESS);
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
getActiveAppInstallationData() {
|
|
268
|
-
|
|
267
|
+
async getActiveAppInstallationData() {
|
|
268
|
+
const { data } = await fetchAppInstallationData(
|
|
269
269
|
this.targetAccountId,
|
|
270
270
|
this.projectId,
|
|
271
271
|
this.activeApp.config.uid,
|
|
272
272
|
this.activeApp.config.auth.requiredScopes,
|
|
273
273
|
this.activeApp.config.auth.optionalScopes
|
|
274
274
|
);
|
|
275
|
+
|
|
276
|
+
return data;
|
|
275
277
|
}
|
|
276
278
|
|
|
277
279
|
async checkPublicAppInstallation() {
|
|
@@ -50,24 +50,26 @@ describe('cli/lib/projectLogsManager', () => {
|
|
|
50
50
|
getProjectConfig.mockResolvedValue(projectConfig);
|
|
51
51
|
ensureProjectExists.mockResolvedValue(projectDetails);
|
|
52
52
|
fetchProjectComponentsMetadata.mockResolvedValue({
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
deployOutput: {
|
|
59
|
-
appId,
|
|
60
|
-
},
|
|
61
|
-
featureComponents: [
|
|
62
|
-
...functions,
|
|
63
|
-
{
|
|
64
|
-
type: {
|
|
65
|
-
name: 'NOT_AN_APP_FUNCTION',
|
|
66
|
-
},
|
|
53
|
+
data: {
|
|
54
|
+
topLevelComponentMetadata: [
|
|
55
|
+
{
|
|
56
|
+
type: {
|
|
57
|
+
name: 'PRIVATE_APP',
|
|
67
58
|
},
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
59
|
+
deployOutput: {
|
|
60
|
+
appId,
|
|
61
|
+
},
|
|
62
|
+
featureComponents: [
|
|
63
|
+
...functions,
|
|
64
|
+
{
|
|
65
|
+
type: {
|
|
66
|
+
name: 'NOT_AN_APP_FUNCTION',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
71
73
|
});
|
|
72
74
|
});
|
|
73
75
|
|
|
@@ -71,14 +71,16 @@ describe('@hubspot/cli/lib/serverlessLogs', () => {
|
|
|
71
71
|
|
|
72
72
|
const fetchLatest = jest.fn(() => {
|
|
73
73
|
return Promise.resolve({
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
data: {
|
|
75
|
+
id: '1234',
|
|
76
|
+
executionTime: 510,
|
|
77
|
+
log: 'Log message',
|
|
78
|
+
error: null,
|
|
79
|
+
status: 'SUCCESS',
|
|
80
|
+
createdAt: 1620232011451,
|
|
81
|
+
memory: '70/128 MB',
|
|
82
|
+
duration: '53.40 ms',
|
|
83
|
+
},
|
|
82
84
|
});
|
|
83
85
|
});
|
|
84
86
|
const latestLogResponse = {
|
|
@@ -110,7 +112,9 @@ describe('@hubspot/cli/lib/serverlessLogs', () => {
|
|
|
110
112
|
},
|
|
111
113
|
},
|
|
112
114
|
};
|
|
113
|
-
const tailCall = jest.fn(() =>
|
|
115
|
+
const tailCall = jest.fn(() =>
|
|
116
|
+
Promise.resolve({ data: latestLogResponse })
|
|
117
|
+
);
|
|
114
118
|
|
|
115
119
|
await tailLogs({
|
|
116
120
|
accountId: ACCOUNT_ID,
|
package/lib/buildAccount.js
CHANGED
|
@@ -15,17 +15,14 @@ const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
|
15
15
|
const { i18n } = require('./lang');
|
|
16
16
|
const { cliAccountNamePrompt } = require('./prompts/accountNamePrompt');
|
|
17
17
|
const SpinniesManager = require('./ui/SpinniesManager');
|
|
18
|
-
const {
|
|
19
|
-
debugErrorAndContext,
|
|
20
|
-
logErrorInstance,
|
|
21
|
-
} = require('./errorHandlers/standardErrors');
|
|
18
|
+
const { debugError, logError } = require('./errorHandlers/index');
|
|
22
19
|
const {
|
|
23
20
|
createDeveloperTestAccount,
|
|
24
|
-
} = require('@hubspot/local-dev-lib/developerTestAccounts');
|
|
21
|
+
} = require('@hubspot/local-dev-lib/api/developerTestAccounts');
|
|
25
22
|
const {
|
|
26
23
|
HUBSPOT_ACCOUNT_TYPES,
|
|
27
24
|
} = require('@hubspot/local-dev-lib/constants/config');
|
|
28
|
-
const { createSandbox } = require('@hubspot/local-dev-lib/
|
|
25
|
+
const { createSandbox } = require('@hubspot/local-dev-lib/api/sandboxHubs');
|
|
29
26
|
const { sandboxApiTypeMap, handleSandboxCreateError } = require('./sandboxes');
|
|
30
27
|
const {
|
|
31
28
|
handleDeveloperTestAccountCreateError,
|
|
@@ -134,10 +131,13 @@ async function buildNewAccount({
|
|
|
134
131
|
try {
|
|
135
132
|
if (isSandbox) {
|
|
136
133
|
const sandboxApiType = sandboxApiTypeMap[accountType]; // API expects sandbox type as 1 or 2.
|
|
137
|
-
|
|
134
|
+
|
|
135
|
+
const { data } = await createSandbox(accountId, name, sandboxApiType);
|
|
136
|
+
result = { name, ...data };
|
|
138
137
|
resultAccountId = result.sandbox.sandboxHubId;
|
|
139
138
|
} else if (isDeveloperTestAccount) {
|
|
140
|
-
|
|
139
|
+
const { data } = await createDeveloperTestAccount(accountId, name);
|
|
140
|
+
result = data;
|
|
141
141
|
resultAccountId = result.id;
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -148,7 +148,7 @@ async function buildNewAccount({
|
|
|
148
148
|
}),
|
|
149
149
|
});
|
|
150
150
|
} catch (err) {
|
|
151
|
-
|
|
151
|
+
debugError(err);
|
|
152
152
|
|
|
153
153
|
SpinniesManager.fail('buildNewAccount', {
|
|
154
154
|
text: i18n(`${spinniesI18nKey}.fail`, {
|
|
@@ -181,7 +181,7 @@ async function buildNewAccount({
|
|
|
181
181
|
force,
|
|
182
182
|
});
|
|
183
183
|
} catch (err) {
|
|
184
|
-
|
|
184
|
+
logError(err);
|
|
185
185
|
throw err;
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -5,15 +5,15 @@ const { getAccountId, getConfig } = require('@hubspot/local-dev-lib/config');
|
|
|
5
5
|
const { i18n } = require('./lang');
|
|
6
6
|
const {
|
|
7
7
|
fetchDeveloperTestAccounts,
|
|
8
|
-
} = require('@hubspot/local-dev-lib/developerTestAccounts');
|
|
8
|
+
} = require('@hubspot/local-dev-lib/api/developerTestAccounts');
|
|
9
9
|
const {
|
|
10
10
|
isMissingScopeError,
|
|
11
11
|
isSpecifiedError,
|
|
12
|
-
} = require('@hubspot/local-dev-lib/errors/
|
|
12
|
+
} = require('@hubspot/local-dev-lib/errors/index');
|
|
13
13
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
14
14
|
const { uiAccountDescription } = require('./ui');
|
|
15
15
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
16
|
-
const {
|
|
16
|
+
const { logError } = require('./errorHandlers/index');
|
|
17
17
|
|
|
18
18
|
const getHasDevTestAccounts = appDeveloperAccountConfig => {
|
|
19
19
|
const config = getConfig();
|
|
@@ -32,31 +32,31 @@ const getHasDevTestAccounts = appDeveloperAccountConfig => {
|
|
|
32
32
|
|
|
33
33
|
const validateDevTestAccountUsageLimits = async accountConfig => {
|
|
34
34
|
const accountId = getAccountId(accountConfig.portalId);
|
|
35
|
-
const
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
const { data } = await fetchDeveloperTestAccounts(accountId);
|
|
36
|
+
if (!data) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const limit = data.maxTestPortals;
|
|
40
|
+
const count = data.results.length;
|
|
41
|
+
if (count >= limit) {
|
|
42
|
+
const hasDevTestAccounts = getHasDevTestAccounts(accountConfig);
|
|
43
|
+
if (hasDevTestAccounts) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
i18n('lib.developerTestAccount.create.failure.alreadyInConfig', {
|
|
46
|
+
accountName: accountConfig.name || accountId,
|
|
47
|
+
limit,
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
} else {
|
|
51
|
+
throw new Error(
|
|
52
|
+
i18n('lib.developerTestAccount.create.failure.limit', {
|
|
53
|
+
accountName: accountConfig.name || accountId,
|
|
54
|
+
limit,
|
|
55
|
+
})
|
|
56
|
+
);
|
|
56
57
|
}
|
|
57
|
-
return response;
|
|
58
58
|
}
|
|
59
|
-
return
|
|
59
|
+
return data;
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
function handleDeveloperTestAccountCreateError({
|
|
@@ -94,7 +94,7 @@ function handleDeveloperTestAccountCreateError({
|
|
|
94
94
|
);
|
|
95
95
|
logger.log('');
|
|
96
96
|
} else {
|
|
97
|
-
|
|
97
|
+
logError(err);
|
|
98
98
|
}
|
|
99
99
|
throw err;
|
|
100
100
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
2
|
+
const {
|
|
3
|
+
isHubSpotHttpError,
|
|
4
|
+
isSystemError,
|
|
5
|
+
isFileSystemError,
|
|
6
|
+
isValidationError,
|
|
7
|
+
isMissingScopeError,
|
|
8
|
+
} = require('@hubspot/local-dev-lib/errors/index');
|
|
9
|
+
const { shouldSuppressError } = require('./suppressError');
|
|
10
|
+
const { i18n } = require('../lang');
|
|
11
|
+
const util = require('util');
|
|
12
|
+
const { isAxiosError } = require('axios');
|
|
13
|
+
|
|
14
|
+
const i18nKey = 'lib.errorHandlers.index';
|
|
15
|
+
|
|
16
|
+
function logError(error, context = {}) {
|
|
17
|
+
debugError(error, context);
|
|
18
|
+
|
|
19
|
+
if (
|
|
20
|
+
shouldSuppressError(error, context) ||
|
|
21
|
+
shouldSuppressError(error, error.context)
|
|
22
|
+
) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (isHubSpotHttpError(error) && context) {
|
|
27
|
+
error.updateContext(context);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (isHubSpotHttpError(error) || isFileSystemError(error)) {
|
|
31
|
+
if (isValidationError(error) || isMissingScopeError(error)) {
|
|
32
|
+
logger.error(error.formattedValidationErrors());
|
|
33
|
+
} else {
|
|
34
|
+
logger.error(error.message);
|
|
35
|
+
}
|
|
36
|
+
} else if (isSystemError(error)) {
|
|
37
|
+
logger.error(error.message);
|
|
38
|
+
} else if (error.message || error.reason) {
|
|
39
|
+
const message = [];
|
|
40
|
+
|
|
41
|
+
[error.message, error.reason].forEach(msg => {
|
|
42
|
+
if (msg) {
|
|
43
|
+
message.push(msg);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
logger.error(message.join(' '));
|
|
47
|
+
} else {
|
|
48
|
+
// Unknown errors
|
|
49
|
+
logger.error(i18n(`${i18nKey}.unknownErrorOccurred`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Logs (debug) the error and context objects.
|
|
55
|
+
*
|
|
56
|
+
* @param {Error} error
|
|
57
|
+
* @param {ApiErrorContext} context
|
|
58
|
+
*/
|
|
59
|
+
function debugError(error, context = {}) {
|
|
60
|
+
if (isHubSpotHttpError(error)) {
|
|
61
|
+
logger.debug(error.toString());
|
|
62
|
+
} else {
|
|
63
|
+
logger.debug(i18n(`${i18nKey}.errorOccurred`, { error }));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (error.cause) {
|
|
67
|
+
logger.debug(
|
|
68
|
+
i18n(`${i18nKey}.errorCause`, {
|
|
69
|
+
cause: isAxiosError(error.cause)
|
|
70
|
+
? error.cause
|
|
71
|
+
: util.inspect(error.cause, false, null, true),
|
|
72
|
+
})
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (context) {
|
|
76
|
+
logger.debug(
|
|
77
|
+
i18n(`${i18nKey}.errorContext`, {
|
|
78
|
+
context: util.inspect(context, false, null, true),
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
class ApiErrorContext {
|
|
85
|
+
constructor(props = {}) {
|
|
86
|
+
/** @type {number} */
|
|
87
|
+
this.accountId = props.accountId;
|
|
88
|
+
/** @type {string} */
|
|
89
|
+
this.request = props.request || '';
|
|
90
|
+
/** @type {string} */
|
|
91
|
+
this.payload = props.payload || '';
|
|
92
|
+
/** @type {string} */
|
|
93
|
+
this.projectName = props.projectName || '';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = {
|
|
98
|
+
logError,
|
|
99
|
+
debugError,
|
|
100
|
+
ApiErrorContext,
|
|
101
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const {
|
|
2
2
|
isSpecifiedError,
|
|
3
3
|
isMissingScopeError,
|
|
4
|
-
} = require('@hubspot/local-dev-lib/errors/
|
|
4
|
+
} = require('@hubspot/local-dev-lib/errors/index');
|
|
5
5
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
6
6
|
const { PLATFORM_VERSION_ERROR_TYPES } = require('../constants');
|
|
7
7
|
const { i18n } = require('../lang');
|
|
@@ -12,7 +12,7 @@ const {
|
|
|
12
12
|
uiCommandReference,
|
|
13
13
|
} = require('../ui');
|
|
14
14
|
|
|
15
|
-
const i18nKey = 'lib.errorHandlers.
|
|
15
|
+
const i18nKey = 'lib.errorHandlers.suppressErrors';
|
|
16
16
|
|
|
17
17
|
function createPlatformVersionError(err, subCategory) {
|
|
18
18
|
let translationKey = 'unspecifiedPlatformVersion';
|
|
@@ -58,7 +58,7 @@ function createPlatformVersionError(err, subCategory) {
|
|
|
58
58
|
uiLine();
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
function
|
|
61
|
+
function shouldSuppressError(err, context = {}) {
|
|
62
62
|
if (isMissingScopeError(err)) {
|
|
63
63
|
logger.error(
|
|
64
64
|
i18n(`${i18nKey}.missingScopeError`, {
|
|
@@ -78,7 +78,7 @@ function overrideErrors(err, context) {
|
|
|
78
78
|
})
|
|
79
79
|
) {
|
|
80
80
|
createPlatformVersionError(
|
|
81
|
-
err,
|
|
81
|
+
err.data,
|
|
82
82
|
PLATFORM_VERSION_ERROR_TYPES.PLATFORM_VERSION_NOT_SPECIFIED
|
|
83
83
|
);
|
|
84
84
|
return true;
|
|
@@ -90,7 +90,7 @@ function overrideErrors(err, context) {
|
|
|
90
90
|
})
|
|
91
91
|
) {
|
|
92
92
|
createPlatformVersionError(
|
|
93
|
-
err,
|
|
93
|
+
err.data,
|
|
94
94
|
PLATFORM_VERSION_ERROR_TYPES.PLATFORM_VERSION_RETIRED
|
|
95
95
|
);
|
|
96
96
|
return true;
|
|
@@ -103,7 +103,7 @@ function overrideErrors(err, context) {
|
|
|
103
103
|
})
|
|
104
104
|
) {
|
|
105
105
|
createPlatformVersionError(
|
|
106
|
-
err,
|
|
106
|
+
err.data,
|
|
107
107
|
PLATFORM_VERSION_ERROR_TYPES.PLATFORM_VERSION_SPECIFIED_DOES_NOT_EXIST
|
|
108
108
|
);
|
|
109
109
|
return true;
|
|
@@ -112,5 +112,5 @@ function overrideErrors(err, context) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
module.exports = {
|
|
115
|
-
|
|
115
|
+
shouldSuppressError,
|
|
116
116
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const {
|
|
2
|
+
fetchEnabledFeatures,
|
|
3
|
+
} = require('@hubspot/local-dev-lib/api/localDevAuth');
|
|
4
|
+
|
|
5
|
+
const hasFeature = async (accountId, feature) => {
|
|
6
|
+
const {
|
|
7
|
+
data: { enabledFeatures },
|
|
8
|
+
} = await fetchEnabledFeatures(accountId);
|
|
9
|
+
|
|
10
|
+
return enabledFeatures[feature];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
hasFeature,
|
|
15
|
+
};
|
package/lib/localDev.js
CHANGED
|
@@ -6,7 +6,7 @@ const {
|
|
|
6
6
|
const {
|
|
7
7
|
isMissingScopeError,
|
|
8
8
|
isSpecifiedError,
|
|
9
|
-
} = require('@hubspot/local-dev-lib/errors/
|
|
9
|
+
} = require('@hubspot/local-dev-lib/errors/index');
|
|
10
10
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
11
11
|
const { getAccountConfig, getEnv } = require('@hubspot/local-dev-lib/config');
|
|
12
12
|
const { createProject } = require('@hubspot/local-dev-lib/api/projects');
|
|
@@ -28,7 +28,6 @@ const { syncSandbox } = require('./sandboxSync');
|
|
|
28
28
|
const {
|
|
29
29
|
validateDevTestAccountUsageLimits,
|
|
30
30
|
} = require('./developerTestAccounts');
|
|
31
|
-
const { logErrorInstance } = require('./errorHandlers/standardErrors');
|
|
32
31
|
const { uiCommandReference, uiLine, uiAccountDescription } = require('./ui');
|
|
33
32
|
const SpinniesManager = require('./ui/SpinniesManager');
|
|
34
33
|
const { i18n } = require('./lang');
|
|
@@ -47,10 +46,7 @@ const {
|
|
|
47
46
|
PROJECT_BUILD_TEXT,
|
|
48
47
|
PROJECT_DEPLOY_TEXT,
|
|
49
48
|
} = require('./constants');
|
|
50
|
-
const {
|
|
51
|
-
logApiErrorInstance,
|
|
52
|
-
ApiErrorContext,
|
|
53
|
-
} = require('./errorHandlers/apiErrors');
|
|
49
|
+
const { logError, ApiErrorContext } = require('./errorHandlers/index');
|
|
54
50
|
const {
|
|
55
51
|
PERSONAL_ACCESS_KEY_AUTH_METHOD,
|
|
56
52
|
} = require('@hubspot/local-dev-lib/constants/auth');
|
|
@@ -82,11 +78,25 @@ const confirmDefaultAccountIsTarget = async accountConfig => {
|
|
|
82
78
|
}
|
|
83
79
|
};
|
|
84
80
|
|
|
85
|
-
// Confirm the default account is
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
81
|
+
// Confirm the default account is supported for the type of apps being developed
|
|
82
|
+
const checkIfDefaultAccountIsSupported = (accountConfig, hasPublicApps) => {
|
|
83
|
+
if (
|
|
84
|
+
hasPublicApps &&
|
|
85
|
+
!(
|
|
86
|
+
isAppDeveloperAccount(accountConfig) ||
|
|
87
|
+
isDeveloperTestAccount(accountConfig)
|
|
88
|
+
)
|
|
89
|
+
) {
|
|
88
90
|
logger.error(
|
|
89
|
-
i18n(`${i18nKey}.
|
|
91
|
+
i18n(`${i18nKey}.checkIfDefaultAccountIsSupported.publicApp`, {
|
|
92
|
+
useCommand: uiCommandReference('hs accounts use'),
|
|
93
|
+
authCommand: uiCommandReference('hs auth'),
|
|
94
|
+
})
|
|
95
|
+
);
|
|
96
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
97
|
+
} else if (!hasPublicApps && isAppDeveloperAccount(accountConfig)) {
|
|
98
|
+
logger.error(
|
|
99
|
+
i18n(`${i18nKey}.checkIfDefaultAccountIsSupported.privateApp`, {
|
|
90
100
|
useCommand: uiCommandReference('hs accounts use'),
|
|
91
101
|
authCommand: uiCommandReference('hs auth'),
|
|
92
102
|
})
|
|
@@ -111,7 +121,7 @@ const checkIfParentAccountIsAuthed = accountConfig => {
|
|
|
111
121
|
};
|
|
112
122
|
|
|
113
123
|
// Confirm the default account is a developer account if developing public apps
|
|
114
|
-
const
|
|
124
|
+
const checkIfAccountFlagIsSupported = (accountConfig, hasPublicApps) => {
|
|
115
125
|
if (hasPublicApps) {
|
|
116
126
|
if (!isDeveloperTestAccount) {
|
|
117
127
|
logger.error(
|
|
@@ -184,7 +194,7 @@ const createSandboxForLocalDev = async (accountId, accountConfig, env) => {
|
|
|
184
194
|
})
|
|
185
195
|
);
|
|
186
196
|
} else {
|
|
187
|
-
|
|
197
|
+
logError(err);
|
|
188
198
|
}
|
|
189
199
|
process.exit(EXIT_CODES.ERROR);
|
|
190
200
|
}
|
|
@@ -223,7 +233,7 @@ const createSandboxForLocalDev = async (accountId, accountConfig, env) => {
|
|
|
223
233
|
});
|
|
224
234
|
return targetAccountId;
|
|
225
235
|
} catch (err) {
|
|
226
|
-
|
|
236
|
+
logError(err);
|
|
227
237
|
process.exit(EXIT_CODES.ERROR);
|
|
228
238
|
}
|
|
229
239
|
};
|
|
@@ -262,7 +272,7 @@ const createDeveloperTestAccountForLocalDev = async (
|
|
|
262
272
|
})
|
|
263
273
|
);
|
|
264
274
|
} else {
|
|
265
|
-
|
|
275
|
+
logError(err);
|
|
266
276
|
}
|
|
267
277
|
process.exit(EXIT_CODES.ERROR);
|
|
268
278
|
}
|
|
@@ -288,7 +298,7 @@ const createDeveloperTestAccountForLocalDev = async (
|
|
|
288
298
|
|
|
289
299
|
return result.id;
|
|
290
300
|
} catch (err) {
|
|
291
|
-
|
|
301
|
+
logError(err);
|
|
292
302
|
process.exit(EXIT_CODES.ERROR);
|
|
293
303
|
}
|
|
294
304
|
};
|
|
@@ -367,7 +377,10 @@ const createNewProjectForLocalDev = async (
|
|
|
367
377
|
});
|
|
368
378
|
|
|
369
379
|
try {
|
|
370
|
-
const project = await createProject(
|
|
380
|
+
const { data: project } = await createProject(
|
|
381
|
+
targetAccountId,
|
|
382
|
+
projectConfig.name
|
|
383
|
+
);
|
|
371
384
|
SpinniesManager.succeed('createProject', {
|
|
372
385
|
text: i18n(`${i18nKey}.createNewProjectForLocalDev.createdProject`, {
|
|
373
386
|
accountIdentifier: uiAccountDescription(targetAccountId),
|
|
@@ -420,7 +433,7 @@ const createInitialBuildForNewProject = async (
|
|
|
420
433
|
);
|
|
421
434
|
logger.log();
|
|
422
435
|
} else {
|
|
423
|
-
|
|
436
|
+
logError(
|
|
424
437
|
initialUploadResult.uploadError,
|
|
425
438
|
new ApiErrorContext({
|
|
426
439
|
accountId: targetAccountId,
|
|
@@ -465,8 +478,8 @@ const getAccountHomeUrl = accountId => {
|
|
|
465
478
|
|
|
466
479
|
module.exports = {
|
|
467
480
|
confirmDefaultAccountIsTarget,
|
|
468
|
-
|
|
469
|
-
|
|
481
|
+
checkIfDefaultAccountIsSupported,
|
|
482
|
+
checkIfAccountFlagIsSupported,
|
|
470
483
|
suggestRecommendedNestedAccount,
|
|
471
484
|
createSandboxForLocalDev,
|
|
472
485
|
createDeveloperTestAccountForLocalDev,
|