@hubspot/cli 5.2.1-beta.1 → 5.2.1-beta.11
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 +1 -1
- package/bin/hs +1 -1
- package/commands/accounts/clean.js +7 -7
- package/commands/accounts/info.js +3 -3
- package/commands/accounts/list.js +7 -18
- package/commands/accounts/remove.js +1 -1
- package/commands/accounts/rename.js +3 -3
- package/commands/accounts/use.js +1 -1
- package/commands/accounts.js +3 -3
- package/commands/auth.js +7 -9
- package/commands/cms/convertFields.js +1 -1
- package/commands/cms/lighthouseScore.js +4 -4
- package/commands/cms/reactModules.js +1 -1
- package/commands/cms.js +3 -3
- package/commands/config/set/allowUsageTracking.js +1 -2
- package/commands/config/set/defaultMode.js +1 -1
- package/commands/config/set/httpTimeout.js +1 -1
- package/commands/config/set.js +1 -1
- package/commands/config.js +3 -3
- package/commands/create/api-sample.js +1 -1
- package/commands/create/module.js +1 -1
- package/commands/create/template.js +1 -1
- package/commands/create.js +1 -1
- package/commands/customObject/create.js +1 -1
- package/commands/customObject/schema/create.js +2 -3
- package/commands/customObject/schema/delete.js +1 -2
- package/commands/customObject/schema/fetch-all.js +1 -2
- package/commands/customObject/schema/fetch.js +1 -2
- package/commands/customObject/schema/list.js +1 -1
- package/commands/customObject/schema/update.js +2 -3
- package/commands/customObject/schema.js +1 -1
- package/commands/customObject.js +3 -3
- package/commands/feedback.js +4 -6
- package/commands/fetch.js +6 -6
- package/commands/filemanager/fetch.js +4 -4
- package/commands/filemanager/upload.js +4 -4
- package/commands/filemanager.js +4 -4
- package/commands/functions/deploy.js +9 -25
- package/commands/functions/list.js +4 -4
- package/commands/functions/server.js +4 -4
- package/commands/functions.js +3 -3
- package/commands/hubdb/clear.js +4 -4
- package/commands/hubdb/create.js +4 -4
- package/commands/hubdb/delete.js +4 -4
- package/commands/hubdb/fetch.js +4 -4
- package/commands/hubdb.js +3 -3
- package/commands/init.js +6 -8
- package/commands/lint.js +3 -3
- package/commands/list.js +4 -4
- package/commands/logs.js +4 -4
- package/commands/module/marketplace-validate.js +5 -5
- package/commands/module.js +3 -3
- package/commands/mv.js +4 -4
- package/commands/open.js +4 -4
- package/commands/project/__tests__/deploy.test.js +431 -0
- package/commands/project/add.js +1 -1
- package/commands/project/cloneApp.js +161 -0
- package/commands/project/create.js +4 -4
- package/commands/project/deploy.js +79 -25
- package/commands/project/dev.js +70 -27
- package/commands/project/download.js +11 -7
- package/commands/project/listBuilds.js +5 -5
- package/commands/project/logs.js +5 -5
- package/commands/project/migrateApp.js +244 -0
- package/commands/project/open.js +12 -8
- package/commands/project/upload.js +13 -8
- package/commands/project/watch.js +4 -4
- package/commands/project.js +7 -3
- package/commands/remove.js +4 -4
- package/commands/sandbox/create.js +22 -18
- package/commands/sandbox/delete.js +10 -7
- package/commands/sandbox/sync.js +8 -8
- package/commands/sandbox.js +5 -4
- package/commands/secrets/addSecret.js +4 -4
- package/commands/secrets/deleteSecret.js +4 -4
- package/commands/secrets/listSecrets.js +4 -4
- package/commands/secrets/updateSecret.js +4 -4
- package/commands/secrets.js +3 -3
- package/commands/theme/generate-selectors.js +1 -1
- package/commands/theme/marketplace-validate.js +5 -5
- package/commands/theme/preview.js +52 -17
- package/commands/theme.js +1 -1
- package/commands/upload.js +5 -5
- package/commands/watch.js +61 -18
- package/jest.config.js +1 -0
- package/lang/en.lyaml +1450 -1371
- package/lib/DevServerManager.js +3 -2
- package/lib/LocalDevManager.js +169 -7
- package/lib/__tests__/{commonOpts.js → commonOpts.test.js} +3 -0
- package/lib/__tests__/downloadProjectPrompt.test.js +31 -0
- package/lib/__tests__/projects.test.js +13 -17
- package/lib/__tests__/{serverlessLogs.js → serverlessLogs.test.js} +1 -0
- package/lib/buildAccount.js +197 -0
- package/lib/commonOpts.js +1 -1
- package/lib/constants.js +12 -1
- package/lib/developerTestAccounts.js +52 -4
- package/lib/errorHandlers/apiErrors.js +1 -1
- package/lib/errorHandlers/overrideErrors.js +1 -1
- package/lib/errorHandlers/standardErrors.js +1 -1
- package/lib/generate-selectors.js +1 -1
- package/lib/localDev.js +102 -52
- package/lib/marketplace-validate.js +11 -3
- package/lib/polling.js +31 -0
- package/lib/process.js +1 -1
- package/lib/projectStructure.js +5 -2
- package/lib/projects.js +68 -15
- package/lib/projectsWatch.js +1 -1
- package/lib/prompts/accountNamePrompt.js +81 -0
- package/lib/prompts/accountsPrompt.js +1 -1
- package/lib/prompts/activeInstallConfirmationPrompt.js +20 -0
- package/lib/prompts/buildIdPrompt.js +8 -17
- package/lib/prompts/cleanUploadPrompt.js +1 -1
- package/lib/prompts/cloneAppLocationPrompt.js +32 -0
- package/lib/prompts/cmsFieldPrompt.js +1 -1
- package/lib/prompts/createApiSamplePrompt.js +1 -1
- package/lib/prompts/createFunctionPrompt.js +1 -1
- package/lib/prompts/createModulePrompt.js +1 -1
- package/lib/prompts/createProjectPrompt.js +32 -10
- package/lib/prompts/createTemplatePrompt.js +1 -1
- package/lib/prompts/downloadProjectPrompt.js +5 -6
- package/lib/prompts/feedbackPrompt.js +1 -1
- package/lib/prompts/folderOverwritePrompt.js +1 -1
- package/lib/prompts/installPublicAppPrompt.js +51 -0
- package/lib/prompts/personalAccessKeyPrompt.js +3 -3
- package/lib/prompts/previewPrompt.js +19 -1
- package/lib/prompts/projectAddPrompt.js +1 -1
- package/lib/prompts/projectDevTargetAccountPrompt.js +48 -6
- package/lib/prompts/projectNamePrompt.js +2 -2
- package/lib/prompts/projectsLogsPrompt.js +1 -1
- package/lib/prompts/sandboxesPrompt.js +13 -42
- package/lib/prompts/secretPrompt.js +1 -1
- package/lib/prompts/selectPublicAppPrompt.js +84 -0
- package/lib/prompts/setAsDefaultAccountPrompt.js +1 -1
- package/lib/prompts/uploadPrompt.js +1 -1
- package/lib/sandboxSync.js +1 -1
- package/lib/sandboxes.js +167 -14
- package/lib/serverlessLogs.js +2 -2
- package/lib/ui/git.js +1 -1
- package/lib/ui/index.js +5 -22
- package/lib/ui/serverlessFunctionLogs.js +1 -1
- package/package.json +7 -6
- package/lib/developerTestAccountCreate.js +0 -186
- package/lib/prompts/developerTestAccountNamePrompt.js +0 -29
- package/lib/prompts/enterAccountNamePrompt.js +0 -33
- package/lib/sandboxCreate.js +0 -319
- /package/lib/__tests__/{validation.js → validation.test.js} +0 -0
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
fetchDeveloperTestAccounts,
|
|
14
14
|
} = require('@hubspot/local-dev-lib/developerTestAccounts');
|
|
15
15
|
|
|
16
|
-
const i18nKey = '
|
|
16
|
+
const i18nKey = 'lib.prompts.projectDevTargetAccountPrompt';
|
|
17
17
|
|
|
18
18
|
const mapNestedAccount = accountConfig => ({
|
|
19
19
|
name: uiAccountDescription(accountConfig.portalId, false),
|
|
@@ -24,6 +24,12 @@ const mapNestedAccount = accountConfig => ({
|
|
|
24
24
|
},
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
+
const getNonConfigDeveloperTestAccountName = account => {
|
|
28
|
+
return `${account.accountName} [${
|
|
29
|
+
HUBSPOT_ACCOUNT_TYPE_STRINGS[HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST]
|
|
30
|
+
}] (${account.id})`;
|
|
31
|
+
};
|
|
32
|
+
|
|
27
33
|
const selectSandboxTargetAccountPrompt = async (
|
|
28
34
|
accounts,
|
|
29
35
|
defaultAccountConfig
|
|
@@ -94,9 +100,11 @@ const selectDeveloperTestTargetAccountPrompt = async (
|
|
|
94
100
|
) => {
|
|
95
101
|
const defaultAccountId = getAccountId(defaultAccountConfig.name);
|
|
96
102
|
let choices = [];
|
|
97
|
-
let
|
|
103
|
+
let devTestAccountsResponse = undefined;
|
|
98
104
|
try {
|
|
99
|
-
|
|
105
|
+
devTestAccountsResponse = await fetchDeveloperTestAccounts(
|
|
106
|
+
defaultAccountId
|
|
107
|
+
);
|
|
100
108
|
} catch (err) {
|
|
101
109
|
logger.debug('Unable to fetch developer test account usage limits: ', err);
|
|
102
110
|
}
|
|
@@ -110,17 +118,37 @@ const selectDeveloperTestTargetAccountPrompt = async (
|
|
|
110
118
|
);
|
|
111
119
|
let disabledMessage = false;
|
|
112
120
|
if (
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
devTestAccountsResponse &&
|
|
122
|
+
devTestAccountsResponse.results.length >=
|
|
123
|
+
devTestAccountsResponse.maxTestPortals
|
|
115
124
|
) {
|
|
116
125
|
disabledMessage = i18n(`${i18nKey}.developerTestAccountLimit`, {
|
|
117
126
|
authCommand: uiCommandReference('hs auth'),
|
|
118
|
-
limit:
|
|
127
|
+
limit: devTestAccountsResponse.maxTestPortals,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let devTestAccountsNotInConfig = [];
|
|
132
|
+
if (devTestAccountsResponse && devTestAccountsResponse.results) {
|
|
133
|
+
const inConfigIds = devTestAccounts.map(d => d.portalId);
|
|
134
|
+
devTestAccountsResponse.results.forEach(acct => {
|
|
135
|
+
if (inConfigIds.indexOf(acct.id) < 0) {
|
|
136
|
+
devTestAccountsNotInConfig.push({
|
|
137
|
+
name: getNonConfigDeveloperTestAccountName(acct),
|
|
138
|
+
value: {
|
|
139
|
+
targetAccountId: acct.id,
|
|
140
|
+
createdNestedAccount: false,
|
|
141
|
+
parentAccountId: defaultAccountId,
|
|
142
|
+
notInConfigAccount: acct,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
}
|
|
119
146
|
});
|
|
120
147
|
}
|
|
121
148
|
|
|
122
149
|
choices = [
|
|
123
150
|
...devTestAccounts.map(mapNestedAccount),
|
|
151
|
+
...devTestAccountsNotInConfig,
|
|
124
152
|
{
|
|
125
153
|
name: i18n(`${i18nKey}.createNewDeveloperTestAccountOption`),
|
|
126
154
|
value: {
|
|
@@ -172,8 +200,22 @@ const confirmDefaultAccountPrompt = async (accountName, accountType) => {
|
|
|
172
200
|
return useDefaultAccount;
|
|
173
201
|
};
|
|
174
202
|
|
|
203
|
+
const confirmUseExistingDeveloperTestAccountPrompt = async account => {
|
|
204
|
+
const { confirmUseExistingDeveloperTestAccount } = await promptUser([
|
|
205
|
+
{
|
|
206
|
+
name: 'confirmUseExistingDeveloperTestAccount',
|
|
207
|
+
type: 'confirm',
|
|
208
|
+
message: i18n(`${i18nKey}.confirmUseExistingDeveloperTestAccount`, {
|
|
209
|
+
accountName: getNonConfigDeveloperTestAccountName(account),
|
|
210
|
+
}),
|
|
211
|
+
},
|
|
212
|
+
]);
|
|
213
|
+
return confirmUseExistingDeveloperTestAccount;
|
|
214
|
+
};
|
|
215
|
+
|
|
175
216
|
module.exports = {
|
|
176
217
|
selectSandboxTargetAccountPrompt,
|
|
177
218
|
selectDeveloperTestTargetAccountPrompt,
|
|
178
219
|
confirmDefaultAccountPrompt,
|
|
220
|
+
confirmUseExistingDeveloperTestAccountPrompt,
|
|
179
221
|
};
|
|
@@ -3,7 +3,7 @@ const { i18n } = require('../lang');
|
|
|
3
3
|
const { ensureProjectExists } = require('../projects');
|
|
4
4
|
const { uiAccountDescription } = require('../ui');
|
|
5
5
|
|
|
6
|
-
const i18nKey = '
|
|
6
|
+
const i18nKey = 'lib.prompts.projectNamePrompt';
|
|
7
7
|
|
|
8
8
|
const projectNamePrompt = (accountId, options = {}) => {
|
|
9
9
|
return promptUser({
|
|
@@ -14,7 +14,7 @@ const projectNamePrompt = (accountId, options = {}) => {
|
|
|
14
14
|
if (typeof val !== 'string' || !val) {
|
|
15
15
|
return i18n(`${i18nKey}.errors.invalidName`);
|
|
16
16
|
}
|
|
17
|
-
const projectExists = await ensureProjectExists(accountId, val, {
|
|
17
|
+
const { projectExists } = await ensureProjectExists(accountId, val, {
|
|
18
18
|
allowCreate: false,
|
|
19
19
|
noLogs: true,
|
|
20
20
|
});
|
|
@@ -10,7 +10,7 @@ const {
|
|
|
10
10
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
11
11
|
const { EXIT_CODES } = require('../enums/exitCodes');
|
|
12
12
|
|
|
13
|
-
const i18nKey = '
|
|
13
|
+
const i18nKey = 'lib.prompts.projectLogsPrompt';
|
|
14
14
|
|
|
15
15
|
const SERVERLESS_FUNCTION_TYPES = {
|
|
16
16
|
APP_FUNCTION: 'app-function',
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
const { promptUser } = require('./promptUtils');
|
|
2
2
|
const { i18n } = require('../lang');
|
|
3
|
-
const { accountNameExistsInConfig } = require('@hubspot/local-dev-lib/config');
|
|
4
3
|
const { uiAccountDescription } = require('../ui');
|
|
5
4
|
const {
|
|
6
5
|
HUBSPOT_ACCOUNT_TYPES,
|
|
7
6
|
} = require('@hubspot/local-dev-lib/constants/config');
|
|
8
7
|
const { isSandbox } = require('../accountTypes');
|
|
9
8
|
|
|
10
|
-
const i18nKey = '
|
|
9
|
+
const i18nKey = 'lib.prompts.sandboxesPrompt';
|
|
11
10
|
|
|
12
11
|
const mapSandboxAccountChoices = portals =>
|
|
13
12
|
portals
|
|
@@ -29,42 +28,6 @@ const mapNonSandboxAccountChoices = portals =>
|
|
|
29
28
|
};
|
|
30
29
|
});
|
|
31
30
|
|
|
32
|
-
const sandboxNamePrompt = (type = HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX) => {
|
|
33
|
-
const isDevelopmentSandbox =
|
|
34
|
-
type === HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX;
|
|
35
|
-
const namePromptMessage = isDevelopmentSandbox
|
|
36
|
-
? `${i18nKey}.name.developmentSandboxMessage`
|
|
37
|
-
: `${i18nKey}.name.message`;
|
|
38
|
-
return promptUser([
|
|
39
|
-
{
|
|
40
|
-
name: 'name',
|
|
41
|
-
message: i18n(namePromptMessage),
|
|
42
|
-
validate(val) {
|
|
43
|
-
if (typeof val !== 'string') {
|
|
44
|
-
return i18n(`${i18nKey}.name.errors.invalidName`);
|
|
45
|
-
} else if (!val.length) {
|
|
46
|
-
return i18n(`${i18nKey}.name.errors.nameRequired`);
|
|
47
|
-
}
|
|
48
|
-
return accountNameExistsInConfig(val)
|
|
49
|
-
? i18n(`${i18nKey}.name.errors.accountNameExists`, { name: val })
|
|
50
|
-
: true;
|
|
51
|
-
},
|
|
52
|
-
default: `New ${isDevelopmentSandbox ? 'development ' : ''}sandbox`,
|
|
53
|
-
},
|
|
54
|
-
]);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const sandboxTypeChoices = [
|
|
58
|
-
{
|
|
59
|
-
name: i18n(`${i18nKey}.type.developer`),
|
|
60
|
-
value: HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX,
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
name: i18n(`${i18nKey}.type.standard`),
|
|
64
|
-
value: HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX,
|
|
65
|
-
},
|
|
66
|
-
];
|
|
67
|
-
|
|
68
31
|
const sandboxTypePrompt = () => {
|
|
69
32
|
return promptUser([
|
|
70
33
|
{
|
|
@@ -72,7 +35,16 @@ const sandboxTypePrompt = () => {
|
|
|
72
35
|
message: i18n(`${i18nKey}.type.message`),
|
|
73
36
|
type: 'list',
|
|
74
37
|
look: false,
|
|
75
|
-
choices:
|
|
38
|
+
choices: [
|
|
39
|
+
{
|
|
40
|
+
name: i18n(`${i18nKey}.type.developer`),
|
|
41
|
+
value: HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: i18n(`${i18nKey}.type.standard`),
|
|
45
|
+
value: HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
76
48
|
default: HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX,
|
|
77
49
|
},
|
|
78
50
|
]);
|
|
@@ -90,8 +62,8 @@ const deleteSandboxPrompt = (config, promptParentAccount = false) => {
|
|
|
90
62
|
name: 'account',
|
|
91
63
|
message: i18n(
|
|
92
64
|
promptParentAccount
|
|
93
|
-
? `${i18nKey}.
|
|
94
|
-
: `${i18nKey}.
|
|
65
|
+
? `${i18nKey}.selectParentAccountName`
|
|
66
|
+
: `${i18nKey}.selectAccountName`
|
|
95
67
|
),
|
|
96
68
|
type: 'list',
|
|
97
69
|
look: false,
|
|
@@ -103,7 +75,6 @@ const deleteSandboxPrompt = (config, promptParentAccount = false) => {
|
|
|
103
75
|
};
|
|
104
76
|
|
|
105
77
|
module.exports = {
|
|
106
|
-
sandboxNamePrompt,
|
|
107
78
|
sandboxTypePrompt,
|
|
108
79
|
deleteSandboxPrompt,
|
|
109
80
|
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const { promptUser } = require('./promptUtils');
|
|
2
|
+
const { i18n } = require('../lang');
|
|
3
|
+
const { uiLine } = require('../ui');
|
|
4
|
+
const { logApiErrorInstance } = require('../errorHandlers/apiErrors');
|
|
5
|
+
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
6
|
+
const {
|
|
7
|
+
fetchPublicAppsForPortal,
|
|
8
|
+
} = require('@hubspot/local-dev-lib/api/appsDev');
|
|
9
|
+
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
10
|
+
|
|
11
|
+
const i18nKey = 'lib.prompts.selectPublicAppPrompt';
|
|
12
|
+
|
|
13
|
+
const fetchPublicAppOptions = async (accountId, accountName, migrateApp) => {
|
|
14
|
+
try {
|
|
15
|
+
const publicApps = await fetchPublicAppsForPortal(accountId);
|
|
16
|
+
const filteredPublicApps = publicApps.filter(
|
|
17
|
+
app => !app.projectId && !app.sourceId
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
if (
|
|
21
|
+
!filteredPublicApps.length ||
|
|
22
|
+
(migrateApp &&
|
|
23
|
+
!filteredPublicApps.find(app => !app.preventProjectMigrations))
|
|
24
|
+
) {
|
|
25
|
+
const headerTranslationKey = migrateApp
|
|
26
|
+
? 'noAppsMigration'
|
|
27
|
+
: 'noAppsClone';
|
|
28
|
+
const messageTranslationKey = migrateApp
|
|
29
|
+
? 'noAppsMigrationMessage'
|
|
30
|
+
: 'noAppsCloneMessage';
|
|
31
|
+
uiLine();
|
|
32
|
+
logger.error(i18n(`${i18nKey}.errors.${headerTranslationKey}`));
|
|
33
|
+
logger.log(
|
|
34
|
+
i18n(`${i18nKey}.errors.${messageTranslationKey}`, { accountName })
|
|
35
|
+
);
|
|
36
|
+
uiLine();
|
|
37
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
38
|
+
}
|
|
39
|
+
return filteredPublicApps;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
logApiErrorInstance(error, { accountId });
|
|
42
|
+
logger.error(i18n(`${i18nKey}.errors.errorFetchingApps`));
|
|
43
|
+
process.exit(EXIT_CODES.ERROR);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const selectPublicAppPrompt = async ({
|
|
48
|
+
accountId,
|
|
49
|
+
accountName,
|
|
50
|
+
migrateApp = false,
|
|
51
|
+
}) => {
|
|
52
|
+
const publicApps = await fetchPublicAppOptions(
|
|
53
|
+
accountId,
|
|
54
|
+
accountName,
|
|
55
|
+
(migrateApp = false)
|
|
56
|
+
);
|
|
57
|
+
const translationKey = migrateApp ? 'selectAppIdMigrate' : 'selectAppIdClone';
|
|
58
|
+
|
|
59
|
+
return promptUser([
|
|
60
|
+
{
|
|
61
|
+
name: 'appId',
|
|
62
|
+
message: i18n(`${i18nKey}.${translationKey}`, {
|
|
63
|
+
accountName,
|
|
64
|
+
}),
|
|
65
|
+
type: 'list',
|
|
66
|
+
choices: publicApps.map(app => {
|
|
67
|
+
if (migrateApp && app.preventProjectMigrations) {
|
|
68
|
+
return {
|
|
69
|
+
name: `${app.name} (${app.id})`,
|
|
70
|
+
disabled: i18n(`${i18nKey}.errors.cannotBeMigrated`),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
name: `${app.name} (${app.id})`,
|
|
75
|
+
value: app.id,
|
|
76
|
+
};
|
|
77
|
+
}),
|
|
78
|
+
},
|
|
79
|
+
]);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
module.exports = {
|
|
83
|
+
selectPublicAppPrompt,
|
|
84
|
+
};
|
|
@@ -5,7 +5,7 @@ const {
|
|
|
5
5
|
const { promptUser } = require('./promptUtils');
|
|
6
6
|
const { i18n } = require('../lang');
|
|
7
7
|
|
|
8
|
-
const i18nKey = '
|
|
8
|
+
const i18nKey = 'lib.prompts.setAsDefaultAccountPrompt';
|
|
9
9
|
|
|
10
10
|
const setAsDefaultAccountPrompt = async accountName => {
|
|
11
11
|
const config = getConfig();
|
|
@@ -3,7 +3,7 @@ const { getCwd } = require('@hubspot/local-dev-lib/path');
|
|
|
3
3
|
const { promptUser } = require('./promptUtils');
|
|
4
4
|
const { i18n } = require('../lang');
|
|
5
5
|
|
|
6
|
-
const i18nKey = '
|
|
6
|
+
const i18nKey = 'lib.prompts.uploadPrompt';
|
|
7
7
|
|
|
8
8
|
const uploadPrompt = (promptOptions = {}) => {
|
|
9
9
|
return promptUser([
|
package/lib/sandboxSync.js
CHANGED
|
@@ -21,7 +21,7 @@ const { getSandboxTypeAsString } = require('./sandboxes');
|
|
|
21
21
|
const { getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
22
22
|
const { uiAccountDescription } = require('./ui');
|
|
23
23
|
|
|
24
|
-
const i18nKey = '
|
|
24
|
+
const i18nKey = 'lib.sandbox.sync';
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* @param {Object} accountConfig - Account config of sandbox portal
|
package/lib/sandboxes.js
CHANGED
|
@@ -7,7 +7,11 @@ const {
|
|
|
7
7
|
fetchTypes,
|
|
8
8
|
getSandboxUsageLimits,
|
|
9
9
|
} = require('@hubspot/local-dev-lib/sandboxes');
|
|
10
|
-
const {
|
|
10
|
+
const {
|
|
11
|
+
getConfig,
|
|
12
|
+
getAccountId,
|
|
13
|
+
getEnv,
|
|
14
|
+
} = require('@hubspot/local-dev-lib/config');
|
|
11
15
|
const CliProgressMultibarManager = require('./ui/CliProgressMultibarManager');
|
|
12
16
|
const { promptUser } = require('./prompts/promptUtils');
|
|
13
17
|
const { isDevelopmentSandbox } = require('./accountTypes');
|
|
@@ -15,6 +19,13 @@ const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
|
15
19
|
const {
|
|
16
20
|
HUBSPOT_ACCOUNT_TYPES,
|
|
17
21
|
} = require('@hubspot/local-dev-lib/constants/config');
|
|
22
|
+
const { uiAccountDescription } = require('./ui');
|
|
23
|
+
const {
|
|
24
|
+
isMissingScopeError,
|
|
25
|
+
isSpecifiedError,
|
|
26
|
+
} = require('@hubspot/local-dev-lib/errors/apiErrors');
|
|
27
|
+
const { getValidEnv } = require('@hubspot/local-dev-lib/environment');
|
|
28
|
+
const { logErrorInstance } = require('./errorHandlers/standardErrors');
|
|
18
29
|
|
|
19
30
|
const syncTypes = {
|
|
20
31
|
OBJECT_RECORDS: 'object-records',
|
|
@@ -39,9 +50,6 @@ const getSandboxTypeAsString = accountType => {
|
|
|
39
50
|
return 'standard';
|
|
40
51
|
};
|
|
41
52
|
|
|
42
|
-
const getSandboxName = config =>
|
|
43
|
-
`[${getSandboxTypeAsString(config.accountType)} sandbox] `;
|
|
44
|
-
|
|
45
53
|
function getHasSandboxesByType(parentAccountConfig, type) {
|
|
46
54
|
const config = getConfig();
|
|
47
55
|
const parentPortalId = getAccountId(parentAccountConfig.portalId);
|
|
@@ -103,9 +111,7 @@ const getSyncTypesWithContactRecordsPrompt = async (
|
|
|
103
111
|
{
|
|
104
112
|
name: 'contactRecordsSyncPrompt',
|
|
105
113
|
type: 'confirm',
|
|
106
|
-
message: i18n(
|
|
107
|
-
`cli.lib.sandbox.sync.confirm.syncContactRecords.${langKey}`
|
|
108
|
-
),
|
|
114
|
+
message: i18n(`lib.sandbox.sync.confirm.syncContactRecords.${langKey}`),
|
|
109
115
|
},
|
|
110
116
|
]);
|
|
111
117
|
if (!contactRecordsSyncPrompt) {
|
|
@@ -138,7 +144,7 @@ const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
|
138
144
|
if (hasDevelopmentSandboxes) {
|
|
139
145
|
throw new Error(
|
|
140
146
|
i18n(
|
|
141
|
-
`
|
|
147
|
+
`lib.sandbox.create.failure.alreadyInConfig.developer.${
|
|
142
148
|
plural ? 'other' : 'one'
|
|
143
149
|
}`,
|
|
144
150
|
{
|
|
@@ -151,7 +157,7 @@ const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
|
151
157
|
const baseUrl = getHubSpotWebsiteOrigin(env);
|
|
152
158
|
throw new Error(
|
|
153
159
|
i18n(
|
|
154
|
-
`
|
|
160
|
+
`lib.sandbox.create.failure.limit.developer.${
|
|
155
161
|
plural ? 'other' : 'one'
|
|
156
162
|
}`,
|
|
157
163
|
{
|
|
@@ -175,7 +181,7 @@ const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
|
175
181
|
if (hasStandardSandboxes) {
|
|
176
182
|
throw new Error(
|
|
177
183
|
i18n(
|
|
178
|
-
`
|
|
184
|
+
`lib.sandbox.create.failure.alreadyInConfig.standard.${
|
|
179
185
|
plural ? 'other' : 'one'
|
|
180
186
|
}`,
|
|
181
187
|
{
|
|
@@ -188,7 +194,7 @@ const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
|
188
194
|
const baseUrl = getHubSpotWebsiteOrigin(env);
|
|
189
195
|
throw new Error(
|
|
190
196
|
i18n(
|
|
191
|
-
`
|
|
197
|
+
`lib.sandbox.create.failure.limit.standard.${
|
|
192
198
|
plural ? 'other' : 'one'
|
|
193
199
|
}`,
|
|
194
200
|
{
|
|
@@ -203,6 +209,153 @@ const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
|
203
209
|
}
|
|
204
210
|
};
|
|
205
211
|
|
|
212
|
+
function handleSandboxCreateError({
|
|
213
|
+
err,
|
|
214
|
+
env,
|
|
215
|
+
accountId,
|
|
216
|
+
name,
|
|
217
|
+
accountConfig,
|
|
218
|
+
}) {
|
|
219
|
+
if (isMissingScopeError(err)) {
|
|
220
|
+
logger.error(
|
|
221
|
+
i18n('lib.sandboxes.create.failure.scopes.message', {
|
|
222
|
+
accountName: uiAccountDescription(accountId),
|
|
223
|
+
})
|
|
224
|
+
);
|
|
225
|
+
const websiteOrigin = getHubSpotWebsiteOrigin(env);
|
|
226
|
+
const url = `${websiteOrigin}/personal-access-key/${accountId}`;
|
|
227
|
+
logger.info(
|
|
228
|
+
i18n('lib.sandboxes.create.failure.scopes.instructions', {
|
|
229
|
+
accountName: uiAccountDescription(accountId),
|
|
230
|
+
url,
|
|
231
|
+
})
|
|
232
|
+
);
|
|
233
|
+
} else if (
|
|
234
|
+
isSpecifiedError(err, {
|
|
235
|
+
statusCode: 403,
|
|
236
|
+
category: 'BANNED',
|
|
237
|
+
subCategory: 'SandboxErrors.USER_ACCESS_NOT_ALLOWED',
|
|
238
|
+
})
|
|
239
|
+
) {
|
|
240
|
+
logger.log('');
|
|
241
|
+
logger.error(
|
|
242
|
+
i18n('lib.sandboxes.create.failure.invalidUser', {
|
|
243
|
+
accountName: name,
|
|
244
|
+
parentAccountName: uiAccountDescription(accountId),
|
|
245
|
+
})
|
|
246
|
+
);
|
|
247
|
+
logger.log('');
|
|
248
|
+
} else if (
|
|
249
|
+
isSpecifiedError(err, {
|
|
250
|
+
statusCode: 403,
|
|
251
|
+
category: 'BANNED',
|
|
252
|
+
subCategory: 'SandboxErrors.DEVELOPMENT_SANDBOX_ACCESS_NOT_ALLOWED',
|
|
253
|
+
})
|
|
254
|
+
) {
|
|
255
|
+
logger.log('');
|
|
256
|
+
logger.error(
|
|
257
|
+
i18n('lib.sandboxes.create.failure.403Gating', {
|
|
258
|
+
accountName: name,
|
|
259
|
+
parentAccountName: uiAccountDescription(accountId),
|
|
260
|
+
accountId,
|
|
261
|
+
})
|
|
262
|
+
);
|
|
263
|
+
logger.log('');
|
|
264
|
+
} else if (
|
|
265
|
+
isSpecifiedError(err, {
|
|
266
|
+
statusCode: 400,
|
|
267
|
+
category: 'VALIDATION_ERROR',
|
|
268
|
+
subCategory:
|
|
269
|
+
'SandboxErrors.NUM_DEVELOPMENT_SANDBOXES_LIMIT_EXCEEDED_ERROR',
|
|
270
|
+
}) &&
|
|
271
|
+
err.error &&
|
|
272
|
+
err.error.message
|
|
273
|
+
) {
|
|
274
|
+
logger.log('');
|
|
275
|
+
const devSandboxLimit = getSandboxLimit(err.error);
|
|
276
|
+
const plural = devSandboxLimit !== 1;
|
|
277
|
+
const hasDevelopmentSandboxes = getHasSandboxesByType(
|
|
278
|
+
accountConfig,
|
|
279
|
+
HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX
|
|
280
|
+
);
|
|
281
|
+
if (hasDevelopmentSandboxes) {
|
|
282
|
+
logger.error(
|
|
283
|
+
i18n(
|
|
284
|
+
`lib.sandboxes.create.failure.alreadyInConfig.developer.${
|
|
285
|
+
plural ? 'other' : 'one'
|
|
286
|
+
}`,
|
|
287
|
+
{
|
|
288
|
+
accountName: uiAccountDescription(accountId),
|
|
289
|
+
limit: devSandboxLimit,
|
|
290
|
+
}
|
|
291
|
+
)
|
|
292
|
+
);
|
|
293
|
+
} else {
|
|
294
|
+
const baseUrl = getHubSpotWebsiteOrigin(getValidEnv(getEnv(accountId)));
|
|
295
|
+
logger.error(
|
|
296
|
+
i18n(
|
|
297
|
+
`lib.sandboxes.create.failure.limit.developer.${
|
|
298
|
+
plural ? 'other' : 'one'
|
|
299
|
+
}`,
|
|
300
|
+
{
|
|
301
|
+
accountName: uiAccountDescription(accountId),
|
|
302
|
+
limit: devSandboxLimit,
|
|
303
|
+
link: `${baseUrl}/sandboxes-developer/${accountId}/development`,
|
|
304
|
+
}
|
|
305
|
+
)
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
logger.log('');
|
|
309
|
+
} else if (
|
|
310
|
+
isSpecifiedError(err, {
|
|
311
|
+
statusCode: 400,
|
|
312
|
+
category: 'VALIDATION_ERROR',
|
|
313
|
+
subCategory: 'SandboxErrors.NUM_STANDARD_SANDBOXES_LIMIT_EXCEEDED_ERROR',
|
|
314
|
+
}) &&
|
|
315
|
+
err.error &&
|
|
316
|
+
err.error.message
|
|
317
|
+
) {
|
|
318
|
+
logger.log('');
|
|
319
|
+
const standardSandboxLimit = getSandboxLimit(err.error);
|
|
320
|
+
const plural = standardSandboxLimit !== 1;
|
|
321
|
+
const hasStandardSandboxes = getHasSandboxesByType(
|
|
322
|
+
accountConfig,
|
|
323
|
+
HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX
|
|
324
|
+
);
|
|
325
|
+
if (hasStandardSandboxes) {
|
|
326
|
+
logger.error(
|
|
327
|
+
i18n(
|
|
328
|
+
`lib.sandboxes.create.failure.alreadyInConfig.standard.${
|
|
329
|
+
plural ? 'other' : 'one'
|
|
330
|
+
}`,
|
|
331
|
+
{
|
|
332
|
+
accountName: uiAccountDescription(accountId),
|
|
333
|
+
limit: standardSandboxLimit,
|
|
334
|
+
}
|
|
335
|
+
)
|
|
336
|
+
);
|
|
337
|
+
} else {
|
|
338
|
+
const baseUrl = getHubSpotWebsiteOrigin(getValidEnv(getEnv(accountId)));
|
|
339
|
+
logger.error(
|
|
340
|
+
i18n(
|
|
341
|
+
`lib.sandboxes.create.failure.limit.standard.${
|
|
342
|
+
plural ? 'other' : 'one'
|
|
343
|
+
}`,
|
|
344
|
+
{
|
|
345
|
+
accountName: uiAccountDescription(accountId),
|
|
346
|
+
limit: standardSandboxLimit,
|
|
347
|
+
link: `${baseUrl}/sandboxes-developer/${accountId}/standard`,
|
|
348
|
+
}
|
|
349
|
+
)
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
logger.log('');
|
|
353
|
+
} else {
|
|
354
|
+
logErrorInstance(err);
|
|
355
|
+
}
|
|
356
|
+
throw err;
|
|
357
|
+
}
|
|
358
|
+
|
|
206
359
|
const ACTIVE_TASK_POLL_INTERVAL = 1000;
|
|
207
360
|
|
|
208
361
|
const isTaskComplete = task => {
|
|
@@ -229,7 +382,7 @@ function pollSyncTaskStatus(
|
|
|
229
382
|
syncStatusUrl,
|
|
230
383
|
allowEarlyTermination = true
|
|
231
384
|
) {
|
|
232
|
-
const i18nKey = '
|
|
385
|
+
const i18nKey = 'lib.sandbox.sync.types';
|
|
233
386
|
const progressBar = CliProgressMultibarManager.init();
|
|
234
387
|
const mergeTasks = {
|
|
235
388
|
'lead-flows': 'forms', // lead-flows are a subset of forms. We combine these in the UI as a single item, so we want to merge here for consistency.
|
|
@@ -244,7 +397,7 @@ function pollSyncTaskStatus(
|
|
|
244
397
|
logger.log('Exiting, sync will continue in the background.');
|
|
245
398
|
logger.log('');
|
|
246
399
|
logger.log(
|
|
247
|
-
i18n('
|
|
400
|
+
i18n('lib.sandbox.sync.info.syncStatus', {
|
|
248
401
|
url: syncStatusUrl,
|
|
249
402
|
})
|
|
250
403
|
);
|
|
@@ -344,7 +497,6 @@ module.exports = {
|
|
|
344
497
|
sandboxTypeMap,
|
|
345
498
|
sandboxApiTypeMap,
|
|
346
499
|
syncTypes,
|
|
347
|
-
getSandboxName,
|
|
348
500
|
getSandboxTypeAsString,
|
|
349
501
|
getHasSandboxesByType,
|
|
350
502
|
getSandboxLimit,
|
|
@@ -352,4 +504,5 @@ module.exports = {
|
|
|
352
504
|
getAvailableSyncTypes,
|
|
353
505
|
getSyncTypesWithContactRecordsPrompt,
|
|
354
506
|
pollSyncTaskStatus,
|
|
507
|
+
handleSandboxCreateError,
|
|
355
508
|
};
|
package/lib/serverlessLogs.js
CHANGED
|
@@ -52,7 +52,7 @@ const tailLogs = async ({
|
|
|
52
52
|
initialAfter = latestLog && base64EncodeString(latestLog.id);
|
|
53
53
|
} catch (e) {
|
|
54
54
|
// A 404 means no latest log exists(never executed)
|
|
55
|
-
if (e.
|
|
55
|
+
if (e.response && e.response.status !== 404) {
|
|
56
56
|
await logServerlessFunctionApiErrorInstance(
|
|
57
57
|
accountId,
|
|
58
58
|
e,
|
|
@@ -68,7 +68,7 @@ const tailLogs = async ({
|
|
|
68
68
|
latestLog = await tailCall(after);
|
|
69
69
|
nextAfter = latestLog.paging.next.after;
|
|
70
70
|
} catch (e) {
|
|
71
|
-
if (e.
|
|
71
|
+
if (e.response && e.response.status !== 404) {
|
|
72
72
|
logApiErrorInstance(
|
|
73
73
|
e,
|
|
74
74
|
new ApiErrorContext({
|
package/lib/ui/git.js
CHANGED
|
@@ -3,7 +3,7 @@ const { checkGitInclusion } = require('@hubspot/local-dev-lib/gitignore');
|
|
|
3
3
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
4
4
|
const { i18n } = require('../lang');
|
|
5
5
|
|
|
6
|
-
const i18nKey = '
|
|
6
|
+
const i18nKey = 'lib.ui.git';
|
|
7
7
|
|
|
8
8
|
function checkAndWarnGitInclusion(configPath) {
|
|
9
9
|
try {
|