@hubspot/cli 5.2.1-beta.7 → 5.2.1-beta.9
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/clean.js +4 -4
- package/commands/accounts/info.js +2 -2
- package/commands/accounts/list.js +2 -2
- package/commands/accounts/rename.js +2 -2
- package/commands/accounts.js +2 -2
- package/commands/auth.js +4 -6
- package/commands/cms/lighthouseScore.js +3 -3
- package/commands/cms.js +2 -2
- package/commands/config.js +2 -2
- package/commands/customObject/schema/create.js +1 -1
- package/commands/customObject/schema/update.js +1 -1
- package/commands/customObject.js +2 -2
- package/commands/fetch.js +5 -5
- package/commands/filemanager/fetch.js +3 -3
- package/commands/filemanager/upload.js +3 -3
- package/commands/filemanager.js +3 -3
- package/commands/functions/deploy.js +3 -3
- package/commands/functions/list.js +3 -3
- package/commands/functions/server.js +3 -3
- package/commands/functions.js +2 -2
- package/commands/hubdb/clear.js +3 -3
- package/commands/hubdb/create.js +3 -3
- package/commands/hubdb/delete.js +3 -3
- package/commands/hubdb/fetch.js +3 -3
- package/commands/hubdb.js +2 -2
- package/commands/init.js +4 -6
- package/commands/lint.js +2 -2
- package/commands/list.js +3 -3
- package/commands/logs.js +3 -3
- package/commands/module/marketplace-validate.js +4 -4
- package/commands/module.js +2 -2
- package/commands/mv.js +3 -3
- package/commands/open.js +3 -3
- package/commands/project/create.js +3 -3
- package/commands/project/deploy.js +3 -3
- package/commands/project/dev.js +12 -4
- package/commands/project/download.js +2 -2
- package/commands/project/listBuilds.js +3 -3
- package/commands/project/logs.js +3 -3
- package/commands/project/migrateApp.js +29 -12
- package/commands/project/open.js +4 -4
- package/commands/project/upload.js +11 -6
- package/commands/project/watch.js +3 -3
- package/commands/project.js +2 -2
- package/commands/remove.js +3 -3
- package/commands/sandbox/create.js +12 -12
- package/commands/sandbox/delete.js +4 -4
- package/commands/sandbox/sync.js +4 -4
- package/commands/sandbox.js +2 -2
- package/commands/secrets/addSecret.js +3 -3
- package/commands/secrets/deleteSecret.js +3 -3
- package/commands/secrets/listSecrets.js +3 -3
- package/commands/secrets/updateSecret.js +3 -3
- package/commands/secrets.js +2 -2
- package/commands/theme/marketplace-validate.js +4 -4
- package/commands/theme/preview.js +2 -2
- package/commands/upload.js +4 -4
- package/commands/watch.js +6 -9
- package/jest.config.js +1 -0
- package/lang/en.lyaml +34 -36
- package/lib/LocalDevManager.js +61 -8
- 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/developerTestAccounts.js +52 -4
- package/lib/localDev.js +31 -19
- package/lib/marketplace-validate.js +11 -3
- package/lib/projects.js +45 -3
- package/lib/prompts/accountNamePrompt.js +81 -0
- package/lib/prompts/activeInstallConfirmationPrompt.js +20 -0
- package/lib/prompts/createProjectPrompt.js +4 -0
- package/lib/prompts/downloadProjectPrompt.js +4 -5
- package/lib/prompts/personalAccessKeyPrompt.js +2 -2
- package/lib/prompts/sandboxesPrompt.js +12 -41
- package/lib/prompts/selectPublicAppPrompt.js +9 -14
- package/lib/sandboxes.js +160 -1
- package/package.json +4 -4
- 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 -318
- /package/lib/__tests__/{validation.js → validation.test.js} +0 -0
package/lib/localDev.js
CHANGED
|
@@ -8,32 +8,26 @@ const {
|
|
|
8
8
|
isSpecifiedError,
|
|
9
9
|
} = require('@hubspot/local-dev-lib/errors/apiErrors');
|
|
10
10
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
11
|
-
const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
|
|
11
|
+
const { getAccountConfig, getEnv } = require('@hubspot/local-dev-lib/config');
|
|
12
12
|
const { createProject } = require('@hubspot/local-dev-lib/api/projects');
|
|
13
|
+
const {
|
|
14
|
+
ENVIRONMENTS,
|
|
15
|
+
} = require('@hubspot/local-dev-lib/constants/environments');
|
|
13
16
|
const {
|
|
14
17
|
confirmDefaultAccountPrompt,
|
|
15
18
|
selectSandboxTargetAccountPrompt,
|
|
16
19
|
selectDeveloperTestTargetAccountPrompt,
|
|
17
20
|
confirmUseExistingDeveloperTestAccountPrompt,
|
|
18
21
|
} = require('./prompts/projectDevTargetAccountPrompt');
|
|
19
|
-
const { sandboxNamePrompt } = require('./prompts/sandboxesPrompt');
|
|
20
|
-
const {
|
|
21
|
-
developerTestAccountNamePrompt,
|
|
22
|
-
} = require('./prompts/developerTestAccountNamePrompt');
|
|
23
22
|
const { confirmPrompt } = require('./prompts/promptUtils');
|
|
24
23
|
const {
|
|
25
24
|
validateSandboxUsageLimits,
|
|
26
25
|
getAvailableSyncTypes,
|
|
27
26
|
} = require('./sandboxes');
|
|
28
|
-
const { buildSandbox } = require('./sandboxCreate');
|
|
29
27
|
const { syncSandbox } = require('./sandboxSync');
|
|
30
28
|
const {
|
|
31
29
|
validateDevTestAccountUsageLimits,
|
|
32
30
|
} = require('./developerTestAccounts');
|
|
33
|
-
const {
|
|
34
|
-
buildDeveloperTestAccount,
|
|
35
|
-
saveDevTestAccountToConfig,
|
|
36
|
-
} = require('./developerTestAccountCreate');
|
|
37
31
|
const { logErrorInstance } = require('./errorHandlers/standardErrors');
|
|
38
32
|
const { uiCommandReference, uiLine, uiAccountDescription } = require('./ui');
|
|
39
33
|
const SpinniesManager = require('./ui/SpinniesManager');
|
|
@@ -60,6 +54,8 @@ const {
|
|
|
60
54
|
const {
|
|
61
55
|
PERSONAL_ACCESS_KEY_AUTH_METHOD,
|
|
62
56
|
} = require('@hubspot/local-dev-lib/constants/auth');
|
|
57
|
+
const { buildNewAccount, saveAccountToConfig } = require('./buildAccount');
|
|
58
|
+
const { hubspotAccountNamePrompt } = require('./prompts/accountNamePrompt');
|
|
63
59
|
|
|
64
60
|
const i18nKey = 'lib.localDev';
|
|
65
61
|
|
|
@@ -167,9 +163,9 @@ const createSandboxForLocalDev = async (accountId, accountConfig, env) => {
|
|
|
167
163
|
process.exit(EXIT_CODES.ERROR);
|
|
168
164
|
}
|
|
169
165
|
try {
|
|
170
|
-
const { name } = await
|
|
171
|
-
HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX
|
|
172
|
-
);
|
|
166
|
+
const { name } = await hubspotAccountNamePrompt({
|
|
167
|
+
accountType: HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX,
|
|
168
|
+
});
|
|
173
169
|
|
|
174
170
|
trackCommandMetadataUsage(
|
|
175
171
|
'sandbox-create',
|
|
@@ -177,9 +173,9 @@ const createSandboxForLocalDev = async (accountId, accountConfig, env) => {
|
|
|
177
173
|
accountId
|
|
178
174
|
);
|
|
179
175
|
|
|
180
|
-
const { result } = await
|
|
176
|
+
const { result } = await buildNewAccount({
|
|
181
177
|
name,
|
|
182
|
-
|
|
178
|
+
accountType: HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX,
|
|
183
179
|
accountConfig,
|
|
184
180
|
env,
|
|
185
181
|
});
|
|
@@ -246,18 +242,22 @@ const createDeveloperTestAccountForLocalDev = async (
|
|
|
246
242
|
}
|
|
247
243
|
|
|
248
244
|
try {
|
|
249
|
-
const { name } = await
|
|
245
|
+
const { name } = await hubspotAccountNamePrompt({
|
|
246
|
+
currentPortalCount,
|
|
247
|
+
accountType: HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST,
|
|
248
|
+
});
|
|
250
249
|
trackCommandMetadataUsage(
|
|
251
250
|
'developer-test-account-create',
|
|
252
251
|
{ step: 'project-dev' },
|
|
253
252
|
accountId
|
|
254
253
|
);
|
|
255
254
|
|
|
256
|
-
const { result } = await
|
|
255
|
+
const { result } = await buildNewAccount({
|
|
257
256
|
name,
|
|
257
|
+
accountType: HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST,
|
|
258
258
|
accountConfig,
|
|
259
259
|
env,
|
|
260
|
-
maxTestPortals,
|
|
260
|
+
portalLimit: maxTestPortals,
|
|
261
261
|
});
|
|
262
262
|
|
|
263
263
|
return result.id;
|
|
@@ -286,7 +286,11 @@ const useExistingDevTestAccount = async (env, account) => {
|
|
|
286
286
|
logger.log('');
|
|
287
287
|
process.exit(EXIT_CODES.SUCCESS);
|
|
288
288
|
}
|
|
289
|
-
const devTestAcctConfigName = await
|
|
289
|
+
const devTestAcctConfigName = await saveAccountToConfig({
|
|
290
|
+
env,
|
|
291
|
+
accountName: account.accountName,
|
|
292
|
+
accountId: account.id,
|
|
293
|
+
});
|
|
290
294
|
logger.success(
|
|
291
295
|
i18n(`lib.developerTestAccount.create.success.configFileUpdated`, {
|
|
292
296
|
accountName: devTestAcctConfigName,
|
|
@@ -426,6 +430,13 @@ const createInitialBuildForNewProject = async (
|
|
|
426
430
|
return initialUploadResult.buildResult;
|
|
427
431
|
};
|
|
428
432
|
|
|
433
|
+
const getAccountHomeUrl = accountId => {
|
|
434
|
+
const baseUrl = getHubSpotWebsiteOrigin(
|
|
435
|
+
getEnv(accountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD
|
|
436
|
+
);
|
|
437
|
+
return `${baseUrl}/home?portalId=${accountId}`;
|
|
438
|
+
};
|
|
439
|
+
|
|
429
440
|
module.exports = {
|
|
430
441
|
confirmDefaultAccountIsTarget,
|
|
431
442
|
checkIfAppDeveloperAccount,
|
|
@@ -436,4 +447,5 @@ module.exports = {
|
|
|
436
447
|
useExistingDevTestAccount,
|
|
437
448
|
createNewProjectForLocalDev,
|
|
438
449
|
createInitialBuildForNewProject,
|
|
450
|
+
getAccountHomeUrl,
|
|
439
451
|
};
|
|
@@ -57,12 +57,20 @@ const fetchValidationResults = async (accountId, validationId) => {
|
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
const processValidationErrors = validationResults => {
|
|
60
|
+
const processValidationErrors = (i18nKey, validationResults) => {
|
|
61
61
|
if (validationResults.errors.length) {
|
|
62
|
-
const { errors } = validationResults;
|
|
62
|
+
const { assetPath, errors } = validationResults;
|
|
63
63
|
|
|
64
64
|
errors.forEach(err => {
|
|
65
|
-
|
|
65
|
+
if (err.failureReasonType === 'DOWNLOAD_EMPTY') {
|
|
66
|
+
logger.error(
|
|
67
|
+
i18n(`${i18nKey}.errors.invalidPath`, {
|
|
68
|
+
path: assetPath,
|
|
69
|
+
})
|
|
70
|
+
);
|
|
71
|
+
} else {
|
|
72
|
+
logger.error(`${err.context}`);
|
|
73
|
+
}
|
|
66
74
|
});
|
|
67
75
|
process.exit(EXIT_CODES.ERROR);
|
|
68
76
|
}
|
package/lib/projects.js
CHANGED
|
@@ -699,9 +699,51 @@ const makePollTaskStatusFunc = ({
|
|
|
699
699
|
|
|
700
700
|
return new Promise((resolve, reject) => {
|
|
701
701
|
const pollInterval = setInterval(async () => {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
702
|
+
let taskStatus;
|
|
703
|
+
try {
|
|
704
|
+
taskStatus = await statusFn(accountId, taskName, taskId);
|
|
705
|
+
} catch (e) {
|
|
706
|
+
logApiErrorInstance(
|
|
707
|
+
e,
|
|
708
|
+
new ApiErrorContext({
|
|
709
|
+
accountId,
|
|
710
|
+
projectName: taskName,
|
|
711
|
+
})
|
|
712
|
+
);
|
|
713
|
+
return reject(
|
|
714
|
+
new Error(
|
|
715
|
+
i18n(
|
|
716
|
+
`${i18nKey}.makePollTaskStatusFunc.errorFetchingTaskStatus`,
|
|
717
|
+
{
|
|
718
|
+
taskType:
|
|
719
|
+
statusText.TYPE_KEY === PROJECT_BUILD_TEXT.TYPE_KEY
|
|
720
|
+
? 'build'
|
|
721
|
+
: 'deploy',
|
|
722
|
+
}
|
|
723
|
+
)
|
|
724
|
+
)
|
|
725
|
+
);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
if (
|
|
729
|
+
!taskStatus ||
|
|
730
|
+
!taskStatus.status ||
|
|
731
|
+
!taskStatus[statusText.SUBTASK_KEY]
|
|
732
|
+
) {
|
|
733
|
+
return reject(
|
|
734
|
+
new Error(
|
|
735
|
+
i18n(
|
|
736
|
+
`${i18nKey}.makePollTaskStatusFunc.errorFetchingTaskStatus`,
|
|
737
|
+
{
|
|
738
|
+
taskType:
|
|
739
|
+
statusText.TYPE_KEY === PROJECT_BUILD_TEXT.TYPE_KEY
|
|
740
|
+
? 'build'
|
|
741
|
+
: 'deploy',
|
|
742
|
+
}
|
|
743
|
+
)
|
|
744
|
+
)
|
|
745
|
+
);
|
|
746
|
+
}
|
|
705
747
|
|
|
706
748
|
const { status, [statusText.SUBTASK_KEY]: subTaskStatus } = taskStatus;
|
|
707
749
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const { accountNameExistsInConfig } = require('@hubspot/local-dev-lib/config');
|
|
2
|
+
const { STRING_WITH_NO_SPACES_REGEX } = require('../regex');
|
|
3
|
+
const { promptUser } = require('./promptUtils');
|
|
4
|
+
const { i18n } = require('../lang');
|
|
5
|
+
const {
|
|
6
|
+
HUBSPOT_ACCOUNT_TYPES,
|
|
7
|
+
} = require('@hubspot/local-dev-lib/constants/config');
|
|
8
|
+
|
|
9
|
+
const i18nKey = 'lib.prompts.accountNamePrompt';
|
|
10
|
+
|
|
11
|
+
const getCliAccountNamePromptConfig = defaultName => ({
|
|
12
|
+
name: 'name',
|
|
13
|
+
message: i18n(`${i18nKey}.enterAccountName`),
|
|
14
|
+
default: defaultName,
|
|
15
|
+
validate(val) {
|
|
16
|
+
if (typeof val !== 'string') {
|
|
17
|
+
return i18n(`${i18nKey}.errors.invalidName`);
|
|
18
|
+
} else if (!val.length) {
|
|
19
|
+
return i18n(`${i18nKey}.errors.nameRequired`);
|
|
20
|
+
} else if (!STRING_WITH_NO_SPACES_REGEX.test(val)) {
|
|
21
|
+
return i18n(`${i18nKey}.errors.spacesInName`);
|
|
22
|
+
}
|
|
23
|
+
return accountNameExistsInConfig(val)
|
|
24
|
+
? i18n(`${i18nKey}.errors.accountNameExists`, { name: val })
|
|
25
|
+
: true;
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const cliAccountNamePrompt = defaultName => {
|
|
30
|
+
return promptUser(getCliAccountNamePromptConfig(defaultName));
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const hubspotAccountNamePrompt = ({ accountType, currentPortalCount = 0 }) => {
|
|
34
|
+
const isDevelopmentSandbox =
|
|
35
|
+
accountType === HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX;
|
|
36
|
+
const isSandbox =
|
|
37
|
+
accountType === HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX ||
|
|
38
|
+
isDevelopmentSandbox;
|
|
39
|
+
const isDeveloperTestAccount =
|
|
40
|
+
accountType === HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST;
|
|
41
|
+
|
|
42
|
+
let promptMessageString;
|
|
43
|
+
let defaultName;
|
|
44
|
+
if (isSandbox) {
|
|
45
|
+
promptMessageString = isDevelopmentSandbox
|
|
46
|
+
? i18n(`${i18nKey}.enterDevelopmentSandboxName`)
|
|
47
|
+
: i18n(`${i18nKey}.enterStandardSandboxName`);
|
|
48
|
+
defaultName = i18n(`${i18nKey}.sandboxDefaultName`, {
|
|
49
|
+
sandboxType: isDevelopmentSandbox ? 'development' : 'standard',
|
|
50
|
+
});
|
|
51
|
+
} else if (isDeveloperTestAccount) {
|
|
52
|
+
promptMessageString = i18n(`${i18nKey}.enterDeveloperTestAccountName`);
|
|
53
|
+
defaultName = i18n(`${i18nKey}.developerTestAccountDefaultName`, {
|
|
54
|
+
count: currentPortalCount + 1,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return promptUser([
|
|
59
|
+
{
|
|
60
|
+
name: 'name',
|
|
61
|
+
message: promptMessageString,
|
|
62
|
+
validate(val) {
|
|
63
|
+
if (typeof val !== 'string') {
|
|
64
|
+
return i18n(`${i18nKey}.errors.invalidName`);
|
|
65
|
+
} else if (!val.length) {
|
|
66
|
+
return i18n(`${i18nKey}.errors.nameRequired`);
|
|
67
|
+
}
|
|
68
|
+
return accountNameExistsInConfig(val)
|
|
69
|
+
? i18n(`${i18nKey}.errors.accountNameExists`, { name: val })
|
|
70
|
+
: true;
|
|
71
|
+
},
|
|
72
|
+
default: defaultName,
|
|
73
|
+
},
|
|
74
|
+
]);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
getCliAccountNamePromptConfig,
|
|
79
|
+
cliAccountNamePrompt,
|
|
80
|
+
hubspotAccountNamePrompt,
|
|
81
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const { promptUser } = require('./promptUtils');
|
|
2
|
+
const { i18n } = require('../lang');
|
|
3
|
+
|
|
4
|
+
const i18nKey = 'lib.prompts.activeInstallConfirmationPrompt';
|
|
5
|
+
|
|
6
|
+
const activeInstallConfirmationPrompt = async () => {
|
|
7
|
+
const { proceed } = await promptUser([
|
|
8
|
+
{
|
|
9
|
+
name: 'proceed',
|
|
10
|
+
message: i18n(`${i18nKey}.message`),
|
|
11
|
+
type: 'confirm',
|
|
12
|
+
default: false,
|
|
13
|
+
},
|
|
14
|
+
]);
|
|
15
|
+
return proceed;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
activeInstallConfirmationPrompt,
|
|
20
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
1
2
|
const path = require('path');
|
|
2
3
|
const { getCwd } = require('@hubspot/local-dev-lib/path');
|
|
3
4
|
const { PROJECT_COMPONENT_TYPES } = require('../../lib/constants');
|
|
@@ -84,6 +85,9 @@ const createProjectPrompt = async (
|
|
|
84
85
|
if (!input) {
|
|
85
86
|
return i18n(`${i18nKey}.errors.locationRequired`);
|
|
86
87
|
}
|
|
88
|
+
if (fs.existsSync(input)) {
|
|
89
|
+
return i18n(`${i18nKey}.errors.invalidLocation`);
|
|
90
|
+
}
|
|
87
91
|
return true;
|
|
88
92
|
},
|
|
89
93
|
},
|
|
@@ -10,9 +10,7 @@ const { i18n } = require('../lang');
|
|
|
10
10
|
|
|
11
11
|
const i18nKey = 'lib.prompts.downloadProjectPrompt';
|
|
12
12
|
|
|
13
|
-
const createProjectsList = async
|
|
14
|
-
const accountId = getAccountId();
|
|
15
|
-
|
|
13
|
+
const createProjectsList = async accountId => {
|
|
16
14
|
try {
|
|
17
15
|
const projects = await fetchProjects(accountId);
|
|
18
16
|
return projects.results;
|
|
@@ -23,7 +21,8 @@ const createProjectsList = async () => {
|
|
|
23
21
|
};
|
|
24
22
|
|
|
25
23
|
const downloadProjectPrompt = async (promptOptions = {}) => {
|
|
26
|
-
const
|
|
24
|
+
const accountId = getAccountId(promptOptions.account);
|
|
25
|
+
const projectsList = await createProjectsList(accountId);
|
|
27
26
|
|
|
28
27
|
return promptUser([
|
|
29
28
|
{
|
|
@@ -33,7 +32,7 @@ const downloadProjectPrompt = async (promptOptions = {}) => {
|
|
|
33
32
|
!projectsList.find(p => p.name === promptOptions.name)
|
|
34
33
|
? i18n(`${i18nKey}.errors.projectNotFound`, {
|
|
35
34
|
projectName: promptOptions.project,
|
|
36
|
-
accountId
|
|
35
|
+
accountId,
|
|
37
36
|
})
|
|
38
37
|
: i18n(`${i18nKey}.selectProject`);
|
|
39
38
|
},
|
|
@@ -7,7 +7,7 @@ const { deleteEmptyConfigFile } = require('@hubspot/local-dev-lib/config');
|
|
|
7
7
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
8
8
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
9
9
|
const { promptUser } = require('./promptUtils');
|
|
10
|
-
const {
|
|
10
|
+
const { getCliAccountNamePromptConfig } = require('./accountNamePrompt');
|
|
11
11
|
const { i18n } = require('../lang');
|
|
12
12
|
const { uiInfoSection } = require('../ui');
|
|
13
13
|
const { EXIT_CODES } = require('../enums/exitCodes');
|
|
@@ -124,7 +124,7 @@ const SCOPES = {
|
|
|
124
124
|
};
|
|
125
125
|
|
|
126
126
|
const OAUTH_FLOW = [
|
|
127
|
-
|
|
127
|
+
getCliAccountNamePromptConfig(),
|
|
128
128
|
ACCOUNT_ID,
|
|
129
129
|
CLIENT_ID,
|
|
130
130
|
CLIENT_SECRET,
|
|
@@ -1,6 +1,5 @@
|
|
|
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,
|
|
@@ -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
|
};
|
|
@@ -35,7 +35,6 @@ const fetchPublicAppOptions = async (accountId, accountName) => {
|
|
|
35
35
|
const selectPublicAppPrompt = async ({
|
|
36
36
|
accountId,
|
|
37
37
|
accountName,
|
|
38
|
-
promptOptions = {},
|
|
39
38
|
migrateApp = false,
|
|
40
39
|
}) => {
|
|
41
40
|
const publicApps = await fetchPublicAppOptions(accountId, accountName);
|
|
@@ -44,21 +43,17 @@ const selectPublicAppPrompt = async ({
|
|
|
44
43
|
return promptUser([
|
|
45
44
|
{
|
|
46
45
|
name: 'appId',
|
|
47
|
-
message: (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
? i18n(`${i18nKey}.errors.invalidAppId`, {
|
|
51
|
-
appId: promptOptions.appId,
|
|
52
|
-
})
|
|
53
|
-
: i18n(`${i18nKey}.${translationKey}`, {
|
|
54
|
-
accountName,
|
|
55
|
-
});
|
|
56
|
-
},
|
|
57
|
-
when:
|
|
58
|
-
!promptOptions.appId ||
|
|
59
|
-
!publicApps.find(a => a.id === promptOptions.appId),
|
|
46
|
+
message: i18n(`${i18nKey}.${translationKey}`, {
|
|
47
|
+
accountName,
|
|
48
|
+
}),
|
|
60
49
|
type: 'list',
|
|
61
50
|
choices: publicApps.map(app => {
|
|
51
|
+
if (app.listingInfo) {
|
|
52
|
+
return {
|
|
53
|
+
name: `${app.name} (${app.id})`,
|
|
54
|
+
disabled: i18n(`${i18nKey}.errors.marketplaceApp`),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
62
57
|
return {
|
|
63
58
|
name: `${app.name} (${app.id})`,
|
|
64
59
|
value: app.id,
|
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',
|
|
@@ -198,6 +209,153 @@ const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
|
198
209
|
}
|
|
199
210
|
};
|
|
200
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
|
+
|
|
201
359
|
const ACTIVE_TASK_POLL_INTERVAL = 1000;
|
|
202
360
|
|
|
203
361
|
const isTaskComplete = task => {
|
|
@@ -346,4 +504,5 @@ module.exports = {
|
|
|
346
504
|
getAvailableSyncTypes,
|
|
347
505
|
getSyncTypesWithContactRecordsPrompt,
|
|
348
506
|
pollSyncTaskStatus,
|
|
507
|
+
handleSandboxCreateError,
|
|
349
508
|
};
|