@hubspot/cli 5.1.4-beta.0 → 5.1.4-beta.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/commands/accounts/list.js +43 -31
- package/commands/project/dev.js +29 -13
- package/commands/sandbox/create.js +6 -7
- package/commands/sandbox/delete.js +8 -11
- package/commands/sandbox/sync.js +18 -17
- package/lang/en.lyaml +2 -2
- package/lib/DevServerManager.js +12 -6
- package/lib/LocalDevManager.js +1 -1
- package/lib/constants.js +11 -0
- package/lib/developerTestAccounts.js +14 -0
- package/lib/prompts/accountsPrompt.js +5 -7
- package/lib/prompts/projectDevTargetAccountPrompt.js +15 -11
- package/lib/prompts/sandboxesPrompt.js +12 -13
- package/lib/{sandbox-create.js → sandboxCreate.js} +100 -13
- package/lib/{sandbox-sync.js → sandboxSync.js} +7 -7
- package/lib/sandboxes.js +43 -125
- package/lib/ui.js +16 -5
- package/package.json +4 -4
|
@@ -12,8 +12,15 @@ const {
|
|
|
12
12
|
} = require('../../lib/commonOpts');
|
|
13
13
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
14
14
|
const { loadAndValidateOptions } = require('../../lib/validation');
|
|
15
|
-
const {
|
|
15
|
+
const { isSandbox, getSandboxName } = require('../../lib/sandboxes');
|
|
16
|
+
const {
|
|
17
|
+
isDeveloperTestAccount,
|
|
18
|
+
DEV_TEST_ACCOUNT_STRING,
|
|
19
|
+
} = require('../../lib/developerTestAccounts');
|
|
16
20
|
const { i18n } = require('../../lib/lang');
|
|
21
|
+
const {
|
|
22
|
+
HUBSPOT_ACCOUNT_TYPES,
|
|
23
|
+
} = require('@hubspot/local-dev-lib/constants/config');
|
|
17
24
|
|
|
18
25
|
const i18nKey = 'cli.commands.accounts.subcommands.list';
|
|
19
26
|
|
|
@@ -22,29 +29,32 @@ exports.describe = i18n(`${i18nKey}.describe`);
|
|
|
22
29
|
|
|
23
30
|
const sortAndMapPortals = portals => {
|
|
24
31
|
const mappedPortalData = {};
|
|
32
|
+
// Standard and app developer portals
|
|
25
33
|
portals
|
|
26
|
-
.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
return 0;
|
|
34
|
-
})
|
|
34
|
+
.filter(p =>
|
|
35
|
+
p.accountType
|
|
36
|
+
? p.accountType === HUBSPOT_ACCOUNT_TYPES.STANDARD ||
|
|
37
|
+
p.accountType === HUBSPOT_ACCOUNT_TYPES.APP_DEVELOPER
|
|
38
|
+
: p.sandboxAccountType === null
|
|
39
|
+
)
|
|
35
40
|
.forEach(portal => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
mappedPortalData[portal.portalId] = [portal];
|
|
42
|
+
});
|
|
43
|
+
// Non-standard portals (sandbox, developer test account)
|
|
44
|
+
portals
|
|
45
|
+
.filter(p =>
|
|
46
|
+
p.accountType
|
|
47
|
+
? isSandbox(p) || isDeveloperTestAccount(p)
|
|
48
|
+
: p.sandboxAccountType !== null
|
|
49
|
+
)
|
|
50
|
+
.forEach(p => {
|
|
51
|
+
if (p.parentAccountId) {
|
|
52
|
+
mappedPortalData[p.parentAccountId] = [
|
|
53
|
+
...(mappedPortalData[p.parentAccountId] || []),
|
|
54
|
+
p,
|
|
45
55
|
];
|
|
46
56
|
} else {
|
|
47
|
-
mappedPortalData[
|
|
57
|
+
mappedPortalData[p.portalId] = [p];
|
|
48
58
|
}
|
|
49
59
|
});
|
|
50
60
|
return mappedPortalData;
|
|
@@ -53,18 +63,20 @@ const sortAndMapPortals = portals => {
|
|
|
53
63
|
const getPortalData = mappedPortalData => {
|
|
54
64
|
const portalData = [];
|
|
55
65
|
Object.values(mappedPortalData).forEach(set => {
|
|
56
|
-
set.forEach(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
`↳ ${
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
set.forEach(portal => {
|
|
67
|
+
let name = portal.name;
|
|
68
|
+
if (isSandbox(portal)) {
|
|
69
|
+
name = `${portal.name} ${getSandboxName(portal)}`;
|
|
70
|
+
if (set.length > 1) {
|
|
71
|
+
name = `↳ ${name}`;
|
|
72
|
+
}
|
|
73
|
+
} else if (isDeveloperTestAccount(portal)) {
|
|
74
|
+
name = `${portal.name} [${DEV_TEST_ACCOUNT_STRING}]`;
|
|
75
|
+
if (set.length > 1) {
|
|
76
|
+
name = `↳ ${name}`;
|
|
77
|
+
}
|
|
67
78
|
}
|
|
79
|
+
portalData.push([name, portal.portalId, portal.authType]);
|
|
68
80
|
});
|
|
69
81
|
});
|
|
70
82
|
return portalData;
|
package/commands/project/dev.js
CHANGED
|
@@ -40,15 +40,14 @@ const {
|
|
|
40
40
|
const { confirmPrompt } = require('../../lib/prompts/promptUtils');
|
|
41
41
|
const {
|
|
42
42
|
selectTargetAccountPrompt,
|
|
43
|
-
|
|
43
|
+
confirmDefaultAccountPrompt,
|
|
44
44
|
} = require('../../lib/prompts/projectDevTargetAccountPrompt');
|
|
45
45
|
const SpinniesManager = require('../../lib/SpinniesManager');
|
|
46
46
|
const LocalDevManager = require('../../lib/LocalDevManager');
|
|
47
|
-
const { isSandbox } = require('../../lib/sandboxes');
|
|
47
|
+
const { isSandbox, getSandboxTypeAsString } = require('../../lib/sandboxes');
|
|
48
48
|
const { sandboxNamePrompt } = require('../../lib/prompts/sandboxesPrompt');
|
|
49
49
|
const {
|
|
50
50
|
validateSandboxUsageLimits,
|
|
51
|
-
DEVELOPER_SANDBOX,
|
|
52
51
|
getAvailableSyncTypes,
|
|
53
52
|
} = require('../../lib/sandboxes');
|
|
54
53
|
const { getValidEnv } = require('@hubspot/local-dev-lib/environment');
|
|
@@ -58,8 +57,8 @@ const {
|
|
|
58
57
|
ERROR_TYPES,
|
|
59
58
|
} = require('@hubspot/cli-lib/lib/constants');
|
|
60
59
|
|
|
61
|
-
const { buildSandbox } = require('../../lib/
|
|
62
|
-
const { syncSandbox } = require('../../lib/
|
|
60
|
+
const { buildSandbox } = require('../../lib/sandboxCreate');
|
|
61
|
+
const { syncSandbox } = require('../../lib/sandboxSync');
|
|
63
62
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
64
63
|
const {
|
|
65
64
|
logApiErrorInstance,
|
|
@@ -70,6 +69,11 @@ const {
|
|
|
70
69
|
isMissingScopeError,
|
|
71
70
|
} = require('@hubspot/local-dev-lib/errors/apiErrors');
|
|
72
71
|
const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors');
|
|
72
|
+
const {
|
|
73
|
+
isDeveloperTestAccount,
|
|
74
|
+
DEV_TEST_ACCOUNT_STRING,
|
|
75
|
+
} = require('../../lib/developerTestAccounts');
|
|
76
|
+
const { DEVELOPER_SANDBOX_TYPE } = require('../../lib/constants');
|
|
73
77
|
|
|
74
78
|
const i18nKey = 'cli.commands.project.subcommands.dev';
|
|
75
79
|
|
|
@@ -99,19 +103,27 @@ exports.handler = async options => {
|
|
|
99
103
|
let targetAccountId = options.account ? accountId : null;
|
|
100
104
|
let createNewSandbox = false;
|
|
101
105
|
const defaultAccountIsSandbox = isSandbox(accountConfig);
|
|
106
|
+
const defaultAccountIsDeveloperTestAccount = isDeveloperTestAccount(
|
|
107
|
+
accountConfig
|
|
108
|
+
);
|
|
102
109
|
|
|
103
|
-
if (
|
|
110
|
+
if (
|
|
111
|
+
!targetAccountId &&
|
|
112
|
+
(defaultAccountIsSandbox || defaultAccountIsDeveloperTestAccount)
|
|
113
|
+
) {
|
|
104
114
|
logger.log();
|
|
105
|
-
const
|
|
115
|
+
const useDefaultAccount = await confirmDefaultAccountPrompt(
|
|
106
116
|
accountConfig.name,
|
|
107
|
-
|
|
117
|
+
defaultAccountIsSandbox
|
|
118
|
+
? `${getSandboxTypeAsString(accountConfig.accountType)} sandbox`
|
|
119
|
+
: DEV_TEST_ACCOUNT_STRING
|
|
108
120
|
);
|
|
109
121
|
|
|
110
|
-
if (
|
|
122
|
+
if (useDefaultAccount) {
|
|
111
123
|
targetAccountId = accountId;
|
|
112
124
|
} else {
|
|
113
125
|
logger.log(
|
|
114
|
-
i18n(`${i18nKey}.logs.
|
|
126
|
+
i18n(`${i18nKey}.logs.declineDefaultAccountExplanation`, {
|
|
115
127
|
useCommand: uiCommandReference('hs accounts use'),
|
|
116
128
|
devCommand: uiCommandReference('hs project dev'),
|
|
117
129
|
})
|
|
@@ -138,7 +150,11 @@ exports.handler = async options => {
|
|
|
138
150
|
|
|
139
151
|
if (createNewSandbox) {
|
|
140
152
|
try {
|
|
141
|
-
await validateSandboxUsageLimits(
|
|
153
|
+
await validateSandboxUsageLimits(
|
|
154
|
+
accountConfig,
|
|
155
|
+
DEVELOPER_SANDBOX_TYPE,
|
|
156
|
+
env
|
|
157
|
+
);
|
|
142
158
|
} catch (err) {
|
|
143
159
|
if (isMissingScopeError(err)) {
|
|
144
160
|
logger.error(
|
|
@@ -160,7 +176,7 @@ exports.handler = async options => {
|
|
|
160
176
|
process.exit(EXIT_CODES.ERROR);
|
|
161
177
|
}
|
|
162
178
|
try {
|
|
163
|
-
const { name } = await sandboxNamePrompt(
|
|
179
|
+
const { name } = await sandboxNamePrompt(DEVELOPER_SANDBOX_TYPE);
|
|
164
180
|
|
|
165
181
|
trackCommandMetadataUsage(
|
|
166
182
|
'sandbox-create',
|
|
@@ -170,7 +186,7 @@ exports.handler = async options => {
|
|
|
170
186
|
|
|
171
187
|
const { result } = await buildSandbox({
|
|
172
188
|
name,
|
|
173
|
-
type:
|
|
189
|
+
type: DEVELOPER_SANDBOX_TYPE,
|
|
174
190
|
accountConfig,
|
|
175
191
|
env,
|
|
176
192
|
});
|
|
@@ -9,13 +9,11 @@ const { loadAndValidateOptions } = require('../../lib/validation');
|
|
|
9
9
|
const { i18n } = require('../../lib/lang');
|
|
10
10
|
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
11
11
|
const { getAccountConfig, getEnv } = require('@hubspot/local-dev-lib/config');
|
|
12
|
-
const { buildSandbox } = require('../../lib/
|
|
13
|
-
const { uiFeatureHighlight } = require('../../lib/ui');
|
|
12
|
+
const { buildSandbox } = require('../../lib/sandboxCreate');
|
|
13
|
+
const { uiFeatureHighlight, uiAccountDescription } = require('../../lib/ui');
|
|
14
14
|
const {
|
|
15
15
|
sandboxTypeMap,
|
|
16
|
-
DEVELOPER_SANDBOX,
|
|
17
16
|
getSandboxTypeAsString,
|
|
18
|
-
getAccountName,
|
|
19
17
|
getAvailableSyncTypes,
|
|
20
18
|
syncTypes,
|
|
21
19
|
validateSandboxUsageLimits,
|
|
@@ -31,12 +29,13 @@ const {
|
|
|
31
29
|
sandboxNamePrompt,
|
|
32
30
|
} = require('../../lib/prompts/sandboxesPrompt');
|
|
33
31
|
const { promptUser } = require('../../lib/prompts/promptUtils');
|
|
34
|
-
const { syncSandbox } = require('../../lib/
|
|
32
|
+
const { syncSandbox } = require('../../lib/sandboxSync');
|
|
35
33
|
const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors');
|
|
36
34
|
const {
|
|
37
35
|
isMissingScopeError,
|
|
38
36
|
} = require('@hubspot/local-dev-lib/errors/apiErrors');
|
|
39
37
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
38
|
+
const { DEVELOPER_SANDBOX_TYPE } = require('../../lib/constants');
|
|
40
39
|
|
|
41
40
|
const i18nKey = 'cli.commands.sandbox.subcommands.create';
|
|
42
41
|
|
|
@@ -123,7 +122,7 @@ exports.handler = async options => {
|
|
|
123
122
|
name: 'sandboxSyncPrompt',
|
|
124
123
|
type: 'confirm',
|
|
125
124
|
message: i18n(`${syncI18nKey}.confirm.createFlow.${sandboxType}`, {
|
|
126
|
-
parentAccountName:
|
|
125
|
+
parentAccountName: uiAccountDescription(accountId),
|
|
127
126
|
sandboxName,
|
|
128
127
|
}),
|
|
129
128
|
},
|
|
@@ -192,7 +191,7 @@ exports.handler = async options => {
|
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
const highlightItems = ['accountsUseCommand', 'projectCreateCommand'];
|
|
195
|
-
if (sandboxType ===
|
|
194
|
+
if (sandboxType === DEVELOPER_SANDBOX_TYPE) {
|
|
196
195
|
highlightItems.push('projectDevCommand');
|
|
197
196
|
} else {
|
|
198
197
|
highlightItems.push('projectUploadCommand');
|
|
@@ -22,7 +22,6 @@ const { deleteSandboxPrompt } = require('../../lib/prompts/sandboxesPrompt');
|
|
|
22
22
|
const {
|
|
23
23
|
getConfig,
|
|
24
24
|
getEnv,
|
|
25
|
-
getAccountConfig,
|
|
26
25
|
removeSandboxAccountFromConfig,
|
|
27
26
|
updateDefaultAccount,
|
|
28
27
|
} = require('@hubspot/local-dev-lib/config');
|
|
@@ -33,8 +32,8 @@ const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
|
33
32
|
const { promptUser } = require('../../lib/prompts/promptUtils');
|
|
34
33
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
35
34
|
|
|
36
|
-
const { getAccountName } = require('../../lib/sandboxes');
|
|
37
35
|
const { getValidEnv } = require('@hubspot/local-dev-lib/environment');
|
|
36
|
+
const { uiAccountDescription } = require('../../lib/ui');
|
|
38
37
|
|
|
39
38
|
const i18nKey = 'cli.commands.sandbox.subcommands.delete';
|
|
40
39
|
|
|
@@ -69,7 +68,6 @@ exports.handler = async options => {
|
|
|
69
68
|
const sandboxAccountId = getAccountId({
|
|
70
69
|
account: account || accountPrompt.account,
|
|
71
70
|
});
|
|
72
|
-
const accountConfig = getAccountConfig(sandboxAccountId);
|
|
73
71
|
const isDefaultAccount =
|
|
74
72
|
sandboxAccountId === getAccountId(config.defaultPortal);
|
|
75
73
|
|
|
@@ -94,7 +92,6 @@ exports.handler = async options => {
|
|
|
94
92
|
}
|
|
95
93
|
}
|
|
96
94
|
|
|
97
|
-
const parentAccount = getAccountConfig(parentAccountId);
|
|
98
95
|
const url = `${baseUrl}/sandboxes/${parentAccountId}`;
|
|
99
96
|
const command = `hs auth ${
|
|
100
97
|
getEnv(sandboxAccountId) === 'qa' ? '--qa' : ''
|
|
@@ -115,14 +112,14 @@ exports.handler = async options => {
|
|
|
115
112
|
|
|
116
113
|
logger.debug(
|
|
117
114
|
i18n(`${i18nKey}.debug.deleting`, {
|
|
118
|
-
account:
|
|
115
|
+
account: uiAccountDescription(sandboxAccountId),
|
|
119
116
|
})
|
|
120
117
|
);
|
|
121
118
|
|
|
122
119
|
if (isDefaultAccount) {
|
|
123
120
|
logger.info(
|
|
124
121
|
i18n(`${i18nKey}.defaultAccountWarning`, {
|
|
125
|
-
account:
|
|
122
|
+
account: uiAccountDescription(sandboxAccountId),
|
|
126
123
|
})
|
|
127
124
|
);
|
|
128
125
|
logger.log('');
|
|
@@ -135,7 +132,7 @@ exports.handler = async options => {
|
|
|
135
132
|
name: 'confirmSandboxDeletePrompt',
|
|
136
133
|
type: 'confirm',
|
|
137
134
|
message: i18n(`${i18nKey}.confirm`, {
|
|
138
|
-
account:
|
|
135
|
+
account: uiAccountDescription(sandboxAccountId),
|
|
139
136
|
}),
|
|
140
137
|
},
|
|
141
138
|
]);
|
|
@@ -177,7 +174,7 @@ exports.handler = async options => {
|
|
|
177
174
|
logger.log('');
|
|
178
175
|
logger.error(
|
|
179
176
|
i18n(`${i18nKey}.failure.invalidKey`, {
|
|
180
|
-
account:
|
|
177
|
+
account: uiAccountDescription(parentAccountId),
|
|
181
178
|
})
|
|
182
179
|
);
|
|
183
180
|
} else if (
|
|
@@ -190,8 +187,8 @@ exports.handler = async options => {
|
|
|
190
187
|
logger.log('');
|
|
191
188
|
logger.error(
|
|
192
189
|
i18n(`${i18nKey}.failure.invalidUser`, {
|
|
193
|
-
accountName:
|
|
194
|
-
parentAccountName:
|
|
190
|
+
accountName: uiAccountDescription(sandboxAccountId),
|
|
191
|
+
parentAccountName: uiAccountDescription(parentAccountId),
|
|
195
192
|
})
|
|
196
193
|
);
|
|
197
194
|
logger.log('');
|
|
@@ -205,7 +202,7 @@ exports.handler = async options => {
|
|
|
205
202
|
logger.log('');
|
|
206
203
|
logger.warn(
|
|
207
204
|
i18n(`${i18nKey}.failure.objectNotFound`, {
|
|
208
|
-
account:
|
|
205
|
+
account: uiAccountDescription(sandboxAccountId),
|
|
209
206
|
})
|
|
210
207
|
);
|
|
211
208
|
logger.log('');
|
package/commands/sandbox/sync.js
CHANGED
|
@@ -13,19 +13,20 @@ const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
|
13
13
|
const { getAccountConfig, getEnv } = require('@hubspot/local-dev-lib/config');
|
|
14
14
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
15
15
|
const { promptUser } = require('../../lib/prompts/promptUtils');
|
|
16
|
-
const { uiLine } = require('../../lib/ui');
|
|
16
|
+
const { uiLine, uiAccountDescription } = require('../../lib/ui');
|
|
17
17
|
const {
|
|
18
|
-
getAccountName,
|
|
19
18
|
sandboxTypeMap,
|
|
20
|
-
DEVELOPER_SANDBOX,
|
|
21
|
-
STANDARD_SANDBOX,
|
|
22
19
|
getAvailableSyncTypes,
|
|
23
20
|
getSyncTypesWithContactRecordsPrompt,
|
|
24
21
|
} = require('../../lib/sandboxes');
|
|
25
|
-
const { syncSandbox } = require('../../lib/
|
|
22
|
+
const { syncSandbox } = require('../../lib/sandboxSync');
|
|
26
23
|
const { getValidEnv } = require('@hubspot/local-dev-lib/environment');
|
|
27
24
|
const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/apiErrors');
|
|
28
25
|
const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors');
|
|
26
|
+
const {
|
|
27
|
+
DEVELOPER_SANDBOX_TYPE,
|
|
28
|
+
STANDARD_SANDBOX_TYPE,
|
|
29
|
+
} = require('../../lib/constants');
|
|
29
30
|
|
|
30
31
|
const i18nKey = 'cli.commands.sandbox.subcommands.sync';
|
|
31
32
|
|
|
@@ -62,7 +63,7 @@ exports.handler = async options => {
|
|
|
62
63
|
logger.log('');
|
|
63
64
|
logger.error(
|
|
64
65
|
i18n(`${i18nKey}.failure.missingParentPortal`, {
|
|
65
|
-
sandboxName:
|
|
66
|
+
sandboxName: uiAccountDescription(accountId),
|
|
66
67
|
})
|
|
67
68
|
);
|
|
68
69
|
process.exit(EXIT_CODES.ERROR);
|
|
@@ -70,9 +71,9 @@ exports.handler = async options => {
|
|
|
70
71
|
|
|
71
72
|
const parentAccountConfig = getAccountConfig(parentAccountId);
|
|
72
73
|
const isDevelopmentSandbox =
|
|
73
|
-
sandboxTypeMap[accountConfig.sandboxAccountType] ===
|
|
74
|
+
sandboxTypeMap[accountConfig.sandboxAccountType] === DEVELOPER_SANDBOX_TYPE;
|
|
74
75
|
const isStandardSandbox =
|
|
75
|
-
sandboxTypeMap[accountConfig.sandboxAccountType] ===
|
|
76
|
+
sandboxTypeMap[accountConfig.sandboxAccountType] === STANDARD_SANDBOX_TYPE;
|
|
76
77
|
|
|
77
78
|
let availableSyncTasks;
|
|
78
79
|
try {
|
|
@@ -90,7 +91,7 @@ exports.handler = async options => {
|
|
|
90
91
|
) {
|
|
91
92
|
logger.error(
|
|
92
93
|
i18n('cli.lib.sandbox.sync.failure.objectNotFound', {
|
|
93
|
-
account:
|
|
94
|
+
account: uiAccountDescription(accountId),
|
|
94
95
|
})
|
|
95
96
|
);
|
|
96
97
|
} else {
|
|
@@ -103,8 +104,8 @@ exports.handler = async options => {
|
|
|
103
104
|
logger.log(i18n(`${i18nKey}.info.developmentSandbox`));
|
|
104
105
|
logger.log(
|
|
105
106
|
i18n(`${i18nKey}.info.sync`, {
|
|
106
|
-
parentAccountName:
|
|
107
|
-
sandboxName:
|
|
107
|
+
parentAccountName: uiAccountDescription(parentAccountId),
|
|
108
|
+
sandboxName: uiAccountDescription(accountId),
|
|
108
109
|
})
|
|
109
110
|
);
|
|
110
111
|
uiLine();
|
|
@@ -119,8 +120,8 @@ exports.handler = async options => {
|
|
|
119
120
|
name: 'confirmSandboxSyncPrompt',
|
|
120
121
|
type: 'confirm',
|
|
121
122
|
message: i18n(`${i18nKey}.confirm.developmentSandbox`, {
|
|
122
|
-
parentAccountName:
|
|
123
|
-
sandboxName:
|
|
123
|
+
parentAccountName: uiAccountDescription(parentAccountId),
|
|
124
|
+
sandboxName: uiAccountDescription(accountId),
|
|
124
125
|
}),
|
|
125
126
|
},
|
|
126
127
|
]);
|
|
@@ -140,8 +141,8 @@ exports.handler = async options => {
|
|
|
140
141
|
);
|
|
141
142
|
logger.log(
|
|
142
143
|
i18n(`${i18nKey}.info.sync`, {
|
|
143
|
-
parentAccountName:
|
|
144
|
-
sandboxName:
|
|
144
|
+
parentAccountName: uiAccountDescription(parentAccountId),
|
|
145
|
+
sandboxName: uiAccountDescription(accountId),
|
|
145
146
|
})
|
|
146
147
|
);
|
|
147
148
|
uiLine();
|
|
@@ -156,8 +157,8 @@ exports.handler = async options => {
|
|
|
156
157
|
name: 'confirmSandboxSyncPrompt',
|
|
157
158
|
type: 'confirm',
|
|
158
159
|
message: i18n(`${i18nKey}.confirm.standardSandbox`, {
|
|
159
|
-
parentAccountName:
|
|
160
|
-
sandboxName:
|
|
160
|
+
parentAccountName: uiAccountDescription(parentAccountId),
|
|
161
|
+
sandboxName: uiAccountDescription(accountId),
|
|
161
162
|
}),
|
|
162
163
|
},
|
|
163
164
|
]);
|
package/lang/en.lyaml
CHANGED
|
@@ -467,7 +467,7 @@ en:
|
|
|
467
467
|
projectMustExistExplanation: "The project {{ projectName }} does not exist in the target account {{ accountIdentifier}}. This command requires the project to exist in the target account."
|
|
468
468
|
choseNotToCreateProject: "Exiting because this command requires the project to exist in the target account."
|
|
469
469
|
initialUploadMessage: "HubSpot Local Dev Server Startup"
|
|
470
|
-
|
|
470
|
+
declineDefaultAccountExplanation: "To develop on a different account, run {{ useCommand }} to change your default account, then re-run {{ devCommand }}."
|
|
471
471
|
status:
|
|
472
472
|
creatingProject: "Creating project {{ projectName }} in {{ accountIdentifier }}"
|
|
473
473
|
createdProject: "Created project {{ projectName }} in {{ accountIdentifier }}"
|
|
@@ -1029,7 +1029,7 @@ en:
|
|
|
1029
1029
|
promptMessage: "[--account] Choose a sandbox under {{ accountIdentifier }} to test with:"
|
|
1030
1030
|
sandboxLimit: "Your account reached the limit of {{ limit }} development sandboxes"
|
|
1031
1031
|
sandboxLimitWithSuggestion: "Your account reached the limit of {{ limit }} development sandboxes. Run {{ authCommand }} to add an existing one to the config."
|
|
1032
|
-
|
|
1032
|
+
confirmDefaultAccount: "Continue testing on {{#bold}}{{ accountName }} ({{ accountType }}){{/bold}}? (Y/n)"
|
|
1033
1033
|
projectLogsPrompt:
|
|
1034
1034
|
projectName:
|
|
1035
1035
|
message: "[--project] Enter the project name:"
|
package/lib/DevServerManager.js
CHANGED
|
@@ -9,6 +9,11 @@ const {
|
|
|
9
9
|
stopPortManagerServer,
|
|
10
10
|
requestPorts,
|
|
11
11
|
} = require('@hubspot/local-dev-lib/portManager');
|
|
12
|
+
const {
|
|
13
|
+
getHubSpotApiOrigin,
|
|
14
|
+
getHubSpotWebsiteOrigin,
|
|
15
|
+
} = require('@hubspot/local-dev-lib/urls');
|
|
16
|
+
const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
|
|
12
17
|
|
|
13
18
|
const i18nKey = 'cli.lib.DevServerManager';
|
|
14
19
|
|
|
@@ -29,7 +34,6 @@ class DevServerManager {
|
|
|
29
34
|
serverInterface: DevModeInterface,
|
|
30
35
|
},
|
|
31
36
|
};
|
|
32
|
-
this.debug = false;
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
async iterateDevServers(callback) {
|
|
@@ -62,19 +66,22 @@ class DevServerManager {
|
|
|
62
66
|
}, {});
|
|
63
67
|
}
|
|
64
68
|
|
|
65
|
-
async setup({ components,
|
|
66
|
-
this.debug = debug;
|
|
69
|
+
async setup({ components, onUploadRequired, accountId }) {
|
|
67
70
|
this.componentsByType = this.arrangeComponentsByType(components);
|
|
68
|
-
|
|
71
|
+
const { env } = getAccountConfig(accountId);
|
|
69
72
|
await startPortManagerServer();
|
|
70
73
|
await this.iterateDevServers(
|
|
71
74
|
async (serverInterface, compatibleComponents) => {
|
|
72
75
|
if (serverInterface.setup) {
|
|
73
76
|
await serverInterface.setup({
|
|
74
77
|
components: compatibleComponents,
|
|
75
|
-
debug,
|
|
76
78
|
onUploadRequired,
|
|
77
79
|
promptUser,
|
|
80
|
+
logger,
|
|
81
|
+
urls: {
|
|
82
|
+
api: getHubSpotApiOrigin(env),
|
|
83
|
+
web: getHubSpotWebsiteOrigin(env),
|
|
84
|
+
},
|
|
78
85
|
});
|
|
79
86
|
}
|
|
80
87
|
}
|
|
@@ -89,7 +96,6 @@ class DevServerManager {
|
|
|
89
96
|
if (serverInterface.start) {
|
|
90
97
|
await serverInterface.start({
|
|
91
98
|
accountId,
|
|
92
|
-
debug: this.debug,
|
|
93
99
|
projectConfig,
|
|
94
100
|
requestPorts,
|
|
95
101
|
});
|
package/lib/LocalDevManager.js
CHANGED
package/lib/constants.js
CHANGED
|
@@ -2,7 +2,18 @@ const HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH =
|
|
|
2
2
|
'HubSpot/hubspot-project-components';
|
|
3
3
|
const DEFAULT_PROJECT_TEMPLATE_BRANCH = 'main';
|
|
4
4
|
|
|
5
|
+
// Sandboxes
|
|
6
|
+
const STANDARD_SANDBOX_TYPE = 'standard';
|
|
7
|
+
const DEVELOPER_SANDBOX_TYPE = 'developer';
|
|
8
|
+
|
|
9
|
+
const STANDARD_SANDBOX = 'STANDARD';
|
|
10
|
+
const DEVELOPER_SANDBOX = 'DEVELOPER';
|
|
11
|
+
|
|
5
12
|
module.exports = {
|
|
6
13
|
HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
|
|
7
14
|
DEFAULT_PROJECT_TEMPLATE_BRANCH,
|
|
15
|
+
STANDARD_SANDBOX_TYPE,
|
|
16
|
+
DEVELOPER_SANDBOX_TYPE,
|
|
17
|
+
STANDARD_SANDBOX,
|
|
18
|
+
DEVELOPER_SANDBOX,
|
|
8
19
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const {
|
|
2
|
+
HUBSPOT_ACCOUNT_TYPES,
|
|
3
|
+
} = require('@hubspot/local-dev-lib/constants/config');
|
|
4
|
+
|
|
5
|
+
const DEV_TEST_ACCOUNT_STRING = 'developer test account';
|
|
6
|
+
|
|
7
|
+
const isDeveloperTestAccount = config =>
|
|
8
|
+
config.accountType &&
|
|
9
|
+
config.accountType === HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST;
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
DEV_TEST_ACCOUNT_STRING,
|
|
13
|
+
isDeveloperTestAccount,
|
|
14
|
+
};
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
const { updateDefaultAccount } = require('@hubspot/local-dev-lib/config');
|
|
2
2
|
const { promptUser } = require('./promptUtils');
|
|
3
3
|
const { i18n } = require('../lang');
|
|
4
|
-
const {
|
|
4
|
+
const { uiAccountDescription } = require('../ui');
|
|
5
5
|
|
|
6
6
|
const mapAccountChoices = portals =>
|
|
7
|
-
portals.map(p => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
});
|
|
7
|
+
portals.map(p => ({
|
|
8
|
+
name: uiAccountDescription(p.portalId, false),
|
|
9
|
+
value: p.name || p.portalId,
|
|
10
|
+
}));
|
|
13
11
|
|
|
14
12
|
const i18nKey = 'cli.commands.accounts.subcommands.use';
|
|
15
13
|
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
const { promptUser } = require('./promptUtils');
|
|
2
2
|
const { i18n } = require('../lang');
|
|
3
3
|
const { uiAccountDescription, uiCommandReference } = require('../ui');
|
|
4
|
-
const { isSandbox
|
|
4
|
+
const { isSandbox } = require('../sandboxes');
|
|
5
5
|
const { getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
6
6
|
const { getSandboxUsageLimits } = require('@hubspot/local-dev-lib/sandboxes');
|
|
7
7
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
8
|
+
const { DEVELOPER_SANDBOX, STANDARD_SANDBOX } = require('../constants');
|
|
8
9
|
|
|
9
10
|
const i18nKey = 'cli.lib.prompts.projectDevTargetAccountPrompt';
|
|
10
11
|
|
|
11
12
|
const mapSandboxAccount = accountConfig => ({
|
|
12
|
-
name:
|
|
13
|
+
name: uiAccountDescription(accountConfig.portalId, false),
|
|
13
14
|
value: {
|
|
14
15
|
targetAccountId: getAccountId(accountConfig.name),
|
|
15
16
|
createNewSandbox: false,
|
|
@@ -33,15 +34,18 @@ const selectTargetAccountPrompt = async (accounts, defaultAccountConfig) => {
|
|
|
33
34
|
);
|
|
34
35
|
let disabledMessage = false;
|
|
35
36
|
|
|
36
|
-
if (
|
|
37
|
-
|
|
37
|
+
if (
|
|
38
|
+
sandboxUsage[DEVELOPER_SANDBOX] &&
|
|
39
|
+
sandboxUsage[DEVELOPER_SANDBOX].available === 0
|
|
40
|
+
) {
|
|
41
|
+
if (sandboxAccounts.length < sandboxUsage[DEVELOPER_SANDBOX].limit) {
|
|
38
42
|
disabledMessage = i18n(`${i18nKey}.sandboxLimitWithSuggestion`, {
|
|
39
43
|
authCommand: uiCommandReference('hs auth'),
|
|
40
|
-
limit: sandboxUsage[
|
|
44
|
+
limit: sandboxUsage[DEVELOPER_SANDBOX].limit,
|
|
41
45
|
});
|
|
42
46
|
} else {
|
|
43
47
|
disabledMessage = i18n(`${i18nKey}.sandboxLimit`, {
|
|
44
|
-
limit: sandboxUsage[
|
|
48
|
+
limit: sandboxUsage[DEVELOPER_SANDBOX].limit,
|
|
45
49
|
});
|
|
46
50
|
}
|
|
47
51
|
}
|
|
@@ -49,10 +53,10 @@ const selectTargetAccountPrompt = async (accounts, defaultAccountConfig) => {
|
|
|
49
53
|
// Order choices by Developer Sandbox -> Standard Sandbox
|
|
50
54
|
const choices = [
|
|
51
55
|
...sandboxAccounts
|
|
52
|
-
.filter(a => a.sandboxAccountType ===
|
|
56
|
+
.filter(a => a.sandboxAccountType === DEVELOPER_SANDBOX)
|
|
53
57
|
.map(mapSandboxAccount),
|
|
54
58
|
...sandboxAccounts
|
|
55
|
-
.filter(a => a.sandboxAccountType ===
|
|
59
|
+
.filter(a => a.sandboxAccountType === STANDARD_SANDBOX)
|
|
56
60
|
.map(mapSandboxAccount),
|
|
57
61
|
{
|
|
58
62
|
name: i18n(`${i18nKey}.createNewSandboxOption`),
|
|
@@ -85,12 +89,12 @@ const selectTargetAccountPrompt = async (accounts, defaultAccountConfig) => {
|
|
|
85
89
|
return targetAccountInfo;
|
|
86
90
|
};
|
|
87
91
|
|
|
88
|
-
const
|
|
92
|
+
const confirmDefaultAccountPrompt = async (accountName, accountType) => {
|
|
89
93
|
const { useDefaultAccount } = await promptUser([
|
|
90
94
|
{
|
|
91
95
|
name: 'useDefaultAccount',
|
|
92
96
|
type: 'confirm',
|
|
93
|
-
message: i18n(`${i18nKey}.
|
|
97
|
+
message: i18n(`${i18nKey}.confirmDefaultAccount`, {
|
|
94
98
|
accountName,
|
|
95
99
|
accountType,
|
|
96
100
|
}),
|
|
@@ -101,5 +105,5 @@ const confirmDefaultSandboxAccountPrompt = async (accountName, accountType) => {
|
|
|
101
105
|
|
|
102
106
|
module.exports = {
|
|
103
107
|
selectTargetAccountPrompt,
|
|
104
|
-
|
|
108
|
+
confirmDefaultAccountPrompt,
|
|
105
109
|
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const { promptUser } = require('./promptUtils');
|
|
2
2
|
const { i18n } = require('../lang');
|
|
3
|
+
const { accountNameExistsInConfig } = require('@hubspot/local-dev-lib/config');
|
|
4
|
+
const { uiAccountDescription } = require('../ui');
|
|
3
5
|
const {
|
|
4
|
-
getSandboxTypeAsString,
|
|
5
|
-
STANDARD_SANDBOX,
|
|
6
6
|
DEVELOPER_SANDBOX,
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
STANDARD_SANDBOX,
|
|
8
|
+
STANDARD_SANDBOX_TYPE,
|
|
9
|
+
DEVELOPER_SANDBOX_TYPE,
|
|
10
|
+
} = require('../constants');
|
|
9
11
|
|
|
10
12
|
const i18nKey = 'cli.lib.prompts.sandboxesPrompt';
|
|
11
13
|
|
|
@@ -13,11 +15,8 @@ const mapSandboxAccountChoices = portals =>
|
|
|
13
15
|
portals
|
|
14
16
|
.filter(p => p.sandboxAccountType && p.sandboxAccountType !== null)
|
|
15
17
|
.map(p => {
|
|
16
|
-
const sandboxName = `[${getSandboxTypeAsString(
|
|
17
|
-
p.sandboxAccountType
|
|
18
|
-
)} sandbox] `;
|
|
19
18
|
return {
|
|
20
|
-
name:
|
|
19
|
+
name: uiAccountDescription(p.portalId, false),
|
|
21
20
|
value: p.name || p.portalId,
|
|
22
21
|
};
|
|
23
22
|
});
|
|
@@ -34,8 +33,8 @@ const mapNonSandboxAccountChoices = portals =>
|
|
|
34
33
|
};
|
|
35
34
|
});
|
|
36
35
|
|
|
37
|
-
const sandboxNamePrompt = (type =
|
|
38
|
-
const isDeveloperSandbox = type ===
|
|
36
|
+
const sandboxNamePrompt = (type = STANDARD_SANDBOX_TYPE) => {
|
|
37
|
+
const isDeveloperSandbox = type === DEVELOPER_SANDBOX_TYPE;
|
|
39
38
|
const namePromptMessage = isDeveloperSandbox
|
|
40
39
|
? `${i18nKey}.name.developmentSandboxMessage`
|
|
41
40
|
: `${i18nKey}.name.message`;
|
|
@@ -61,11 +60,11 @@ const sandboxNamePrompt = (type = STANDARD_SANDBOX) => {
|
|
|
61
60
|
const sandboxTypeChoices = [
|
|
62
61
|
{
|
|
63
62
|
name: i18n(`${i18nKey}.type.developer`),
|
|
64
|
-
value:
|
|
63
|
+
value: DEVELOPER_SANDBOX,
|
|
65
64
|
},
|
|
66
65
|
{
|
|
67
66
|
name: i18n(`${i18nKey}.type.standard`),
|
|
68
|
-
value:
|
|
67
|
+
value: STANDARD_SANDBOX,
|
|
69
68
|
},
|
|
70
69
|
];
|
|
71
70
|
|
|
@@ -77,7 +76,7 @@ const sandboxTypePrompt = () => {
|
|
|
77
76
|
type: 'list',
|
|
78
77
|
look: false,
|
|
79
78
|
choices: sandboxTypeChoices,
|
|
80
|
-
default:
|
|
79
|
+
default: DEVELOPER_SANDBOX,
|
|
81
80
|
},
|
|
82
81
|
]);
|
|
83
82
|
};
|
|
@@ -2,10 +2,7 @@ const SpinniesManager = require('./SpinniesManager');
|
|
|
2
2
|
const {
|
|
3
3
|
getSandboxLimit,
|
|
4
4
|
getHasSandboxesByType,
|
|
5
|
-
saveSandboxToConfig,
|
|
6
5
|
sandboxApiTypeMap,
|
|
7
|
-
STANDARD_SANDBOX,
|
|
8
|
-
DEVELOPER_SANDBOX,
|
|
9
6
|
} = require('./sandboxes');
|
|
10
7
|
const { i18n } = require('./lang');
|
|
11
8
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
@@ -21,9 +18,99 @@ const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
|
21
18
|
const { getEnv, getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
22
19
|
const { createSandbox } = require('@hubspot/local-dev-lib/sandboxes');
|
|
23
20
|
const { getValidEnv } = require('@hubspot/local-dev-lib/environment');
|
|
21
|
+
const {
|
|
22
|
+
getAccessToken,
|
|
23
|
+
updateConfigWithAccessToken,
|
|
24
|
+
} = require('@hubspot/local-dev-lib/personalAccessKey');
|
|
25
|
+
const { uiAccountDescription } = require('./ui');
|
|
26
|
+
const {
|
|
27
|
+
DEVELOPER_SANDBOX_TYPE,
|
|
28
|
+
STANDARD_SANDBOX_TYPE,
|
|
29
|
+
} = require('./constants');
|
|
30
|
+
const {
|
|
31
|
+
personalAccessKeyPrompt,
|
|
32
|
+
} = require('./prompts/personalAccessKeyPrompt');
|
|
33
|
+
const { enterAccountNamePrompt } = require('./prompts/enterAccountNamePrompt');
|
|
34
|
+
const {
|
|
35
|
+
accountNameExistsInConfig,
|
|
36
|
+
writeConfig,
|
|
37
|
+
updateAccountConfig,
|
|
38
|
+
} = require('@hubspot/local-dev-lib/config');
|
|
24
39
|
|
|
25
40
|
const i18nKey = 'cli.lib.sandbox.create';
|
|
26
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @param {String} env - Environment (QA/Prod)
|
|
44
|
+
* @param {Object} result - Sandbox instance returned from API
|
|
45
|
+
* @param {Boolean} force - Force flag to skip prompt
|
|
46
|
+
* @returns {String} validName saved into config
|
|
47
|
+
*/
|
|
48
|
+
const saveSandboxToConfig = async (env, result, force = false) => {
|
|
49
|
+
let personalAccessKey = result.personalAccessKey;
|
|
50
|
+
if (!personalAccessKey) {
|
|
51
|
+
const configData = await personalAccessKeyPrompt({
|
|
52
|
+
env,
|
|
53
|
+
account: result.sandbox.sandboxHubId,
|
|
54
|
+
});
|
|
55
|
+
personalAccessKey = configData.personalAccessKey;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let updatedConfig;
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const token = await getAccessToken(personalAccessKey, env);
|
|
62
|
+
updatedConfig = await updateConfigWithAccessToken(
|
|
63
|
+
token,
|
|
64
|
+
personalAccessKey,
|
|
65
|
+
env
|
|
66
|
+
);
|
|
67
|
+
} catch (e) {
|
|
68
|
+
logErrorInstance(e);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!updatedConfig) {
|
|
72
|
+
throw new Error('Failed to update config with personal access key.');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let validName = updatedConfig.name;
|
|
76
|
+
if (!updatedConfig.name) {
|
|
77
|
+
const nameForConfig = result.sandbox.name
|
|
78
|
+
.toLowerCase()
|
|
79
|
+
.split(' ')
|
|
80
|
+
.join('-');
|
|
81
|
+
validName = nameForConfig;
|
|
82
|
+
const invalidAccountName = accountNameExistsInConfig(nameForConfig);
|
|
83
|
+
if (invalidAccountName) {
|
|
84
|
+
if (!force) {
|
|
85
|
+
logger.log('');
|
|
86
|
+
logger.warn(
|
|
87
|
+
i18n(
|
|
88
|
+
`cli.lib.prompts.enterAccountNamePrompt.errors.accountNameExists`,
|
|
89
|
+
{ name: nameForConfig }
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
const { name: promptName } = await enterAccountNamePrompt(
|
|
93
|
+
nameForConfig + `_${result.sandbox.sandboxHubId}`
|
|
94
|
+
);
|
|
95
|
+
validName = promptName;
|
|
96
|
+
} else {
|
|
97
|
+
// Basic invalid name handling when force flag is passed
|
|
98
|
+
validName = nameForConfig + `_${result.sandbox.sandboxHubId}`;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
updateAccountConfig({
|
|
103
|
+
...updatedConfig,
|
|
104
|
+
environment: updatedConfig.env,
|
|
105
|
+
tokenInfo: updatedConfig.auth.tokenInfo,
|
|
106
|
+
name: validName,
|
|
107
|
+
});
|
|
108
|
+
writeConfig();
|
|
109
|
+
|
|
110
|
+
logger.log('');
|
|
111
|
+
return validName;
|
|
112
|
+
};
|
|
113
|
+
|
|
27
114
|
/**
|
|
28
115
|
* @param {String} name - Name of sandbox
|
|
29
116
|
* @param {String} type - Sandbox type to be created (standard/developer)
|
|
@@ -75,14 +162,14 @@ const buildSandbox = async ({
|
|
|
75
162
|
if (isMissingScopeError(err)) {
|
|
76
163
|
logger.error(
|
|
77
164
|
i18n(`${i18nKey}.failure.scopes.message`, {
|
|
78
|
-
accountName:
|
|
165
|
+
accountName: uiAccountDescription(accountId),
|
|
79
166
|
})
|
|
80
167
|
);
|
|
81
168
|
const websiteOrigin = getHubSpotWebsiteOrigin(env);
|
|
82
169
|
const url = `${websiteOrigin}/personal-access-key/${accountId}`;
|
|
83
170
|
logger.info(
|
|
84
171
|
i18n(`${i18nKey}.failure.scopes.instructions`, {
|
|
85
|
-
accountName:
|
|
172
|
+
accountName: uiAccountDescription(accountId),
|
|
86
173
|
url,
|
|
87
174
|
})
|
|
88
175
|
);
|
|
@@ -97,7 +184,7 @@ const buildSandbox = async ({
|
|
|
97
184
|
logger.error(
|
|
98
185
|
i18n(`${i18nKey}.failure.invalidUser`, {
|
|
99
186
|
accountName: name,
|
|
100
|
-
parentAccountName:
|
|
187
|
+
parentAccountName: uiAccountDescription(accountId),
|
|
101
188
|
})
|
|
102
189
|
);
|
|
103
190
|
logger.log('');
|
|
@@ -112,7 +199,7 @@ const buildSandbox = async ({
|
|
|
112
199
|
logger.error(
|
|
113
200
|
i18n(`${i18nKey}.failure.403Gating`, {
|
|
114
201
|
accountName: name,
|
|
115
|
-
parentAccountName:
|
|
202
|
+
parentAccountName: uiAccountDescription(accountId),
|
|
116
203
|
accountId,
|
|
117
204
|
})
|
|
118
205
|
);
|
|
@@ -132,7 +219,7 @@ const buildSandbox = async ({
|
|
|
132
219
|
const plural = devSandboxLimit !== 1;
|
|
133
220
|
const hasDevelopmentSandboxes = getHasSandboxesByType(
|
|
134
221
|
accountConfig,
|
|
135
|
-
|
|
222
|
+
DEVELOPER_SANDBOX_TYPE
|
|
136
223
|
);
|
|
137
224
|
if (hasDevelopmentSandboxes) {
|
|
138
225
|
logger.error(
|
|
@@ -141,7 +228,7 @@ const buildSandbox = async ({
|
|
|
141
228
|
plural ? 'other' : 'one'
|
|
142
229
|
}`,
|
|
143
230
|
{
|
|
144
|
-
accountName:
|
|
231
|
+
accountName: uiAccountDescription(accountId),
|
|
145
232
|
limit: devSandboxLimit,
|
|
146
233
|
}
|
|
147
234
|
)
|
|
@@ -152,7 +239,7 @@ const buildSandbox = async ({
|
|
|
152
239
|
i18n(
|
|
153
240
|
`${i18nKey}.failure.limit.developer.${plural ? 'other' : 'one'}`,
|
|
154
241
|
{
|
|
155
|
-
accountName:
|
|
242
|
+
accountName: uiAccountDescription(accountId),
|
|
156
243
|
limit: devSandboxLimit,
|
|
157
244
|
link: `${baseUrl}/sandboxes-developer/${accountId}/development`,
|
|
158
245
|
}
|
|
@@ -175,7 +262,7 @@ const buildSandbox = async ({
|
|
|
175
262
|
const plural = standardSandboxLimit !== 1;
|
|
176
263
|
const hasStandardSandboxes = getHasSandboxesByType(
|
|
177
264
|
accountConfig,
|
|
178
|
-
|
|
265
|
+
STANDARD_SANDBOX_TYPE
|
|
179
266
|
);
|
|
180
267
|
if (hasStandardSandboxes) {
|
|
181
268
|
logger.error(
|
|
@@ -184,7 +271,7 @@ const buildSandbox = async ({
|
|
|
184
271
|
plural ? 'other' : 'one'
|
|
185
272
|
}`,
|
|
186
273
|
{
|
|
187
|
-
accountName:
|
|
274
|
+
accountName: uiAccountDescription(accountId),
|
|
188
275
|
limit: standardSandboxLimit,
|
|
189
276
|
}
|
|
190
277
|
)
|
|
@@ -195,7 +282,7 @@ const buildSandbox = async ({
|
|
|
195
282
|
i18n(
|
|
196
283
|
`${i18nKey}.failure.limit.standard.${plural ? 'other' : 'one'}`,
|
|
197
284
|
{
|
|
198
|
-
accountName:
|
|
285
|
+
accountName: uiAccountDescription(accountId),
|
|
199
286
|
limit: standardSandboxLimit,
|
|
200
287
|
link: `${baseUrl}/sandboxes-developer/${accountId}/standard`,
|
|
201
288
|
}
|
|
@@ -5,8 +5,6 @@ const { i18n } = require('./lang');
|
|
|
5
5
|
const {
|
|
6
6
|
getAvailableSyncTypes,
|
|
7
7
|
pollSyncTaskStatus,
|
|
8
|
-
getAccountName,
|
|
9
|
-
DEVELOPER_SANDBOX,
|
|
10
8
|
sandboxTypeMap,
|
|
11
9
|
syncTypes,
|
|
12
10
|
} = require('./sandboxes');
|
|
@@ -22,6 +20,7 @@ const {
|
|
|
22
20
|
const { getSandboxTypeAsString } = require('./sandboxes');
|
|
23
21
|
const { getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
24
22
|
const { uiAccountDescription } = require('./ui');
|
|
23
|
+
const { DEVELOPER_SANDBOX_TYPE } = require('./constants');
|
|
25
24
|
|
|
26
25
|
const i18nKey = 'cli.lib.sandbox.sync';
|
|
27
26
|
|
|
@@ -89,7 +88,8 @@ const syncSandbox = async ({
|
|
|
89
88
|
});
|
|
90
89
|
if (
|
|
91
90
|
skipPolling &&
|
|
92
|
-
sandboxTypeMap[accountConfig.sandboxAccountType] ===
|
|
91
|
+
sandboxTypeMap[accountConfig.sandboxAccountType] ===
|
|
92
|
+
DEVELOPER_SANDBOX_TYPE
|
|
93
93
|
) {
|
|
94
94
|
if (syncTasks.some(t => t.type === syncTypes.OBJECT_RECORDS)) {
|
|
95
95
|
logger.log(i18n(`${i18nKey}.loading.skipPollingWithContacts`));
|
|
@@ -109,7 +109,7 @@ const syncSandbox = async ({
|
|
|
109
109
|
if (isMissingScopeError(err)) {
|
|
110
110
|
logger.error(
|
|
111
111
|
i18n(`${i18nKey}.failure.missingScopes`, {
|
|
112
|
-
accountName:
|
|
112
|
+
accountName: uiAccountDescription(parentAccountId),
|
|
113
113
|
})
|
|
114
114
|
);
|
|
115
115
|
} else if (
|
|
@@ -122,7 +122,7 @@ const syncSandbox = async ({
|
|
|
122
122
|
logger.error(
|
|
123
123
|
i18n(`${i18nKey}.failure.invalidUser`, {
|
|
124
124
|
accountName: uiAccountDescription(accountId),
|
|
125
|
-
parentAccountName:
|
|
125
|
+
parentAccountName: uiAccountDescription(parentAccountId),
|
|
126
126
|
})
|
|
127
127
|
);
|
|
128
128
|
} else if (
|
|
@@ -147,7 +147,7 @@ const syncSandbox = async ({
|
|
|
147
147
|
// This will only trigger if a user is not a super admin of the target account.
|
|
148
148
|
logger.error(
|
|
149
149
|
i18n(`${i18nKey}.failure.notSuperAdmin`, {
|
|
150
|
-
account:
|
|
150
|
+
account: uiAccountDescription(accountId),
|
|
151
151
|
})
|
|
152
152
|
);
|
|
153
153
|
} else if (
|
|
@@ -159,7 +159,7 @@ const syncSandbox = async ({
|
|
|
159
159
|
) {
|
|
160
160
|
logger.error(
|
|
161
161
|
i18n(`${i18nKey}.failure.objectNotFound`, {
|
|
162
|
-
account:
|
|
162
|
+
account: uiAccountDescription(accountId),
|
|
163
163
|
})
|
|
164
164
|
);
|
|
165
165
|
} else {
|
package/lib/sandboxes.js
CHANGED
|
@@ -1,49 +1,39 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
1
|
const { i18n, MISSING_LANGUAGE_DATA_PREFIX } = require('./lang');
|
|
3
2
|
const { handleExit, handleKeypress } = require('./process');
|
|
4
3
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
5
|
-
const {
|
|
6
|
-
getAccessToken,
|
|
7
|
-
updateConfigWithAccessToken,
|
|
8
|
-
} = require('@hubspot/local-dev-lib/personalAccessKey');
|
|
9
4
|
const { EXIT_CODES } = require('./enums/exitCodes');
|
|
10
|
-
const { enterAccountNamePrompt } = require('./prompts/enterAccountNamePrompt');
|
|
11
5
|
const {
|
|
12
6
|
fetchTaskStatus,
|
|
13
7
|
fetchTypes,
|
|
14
8
|
getSandboxUsageLimits,
|
|
15
9
|
} = require('@hubspot/local-dev-lib/sandboxes');
|
|
16
|
-
const {
|
|
17
|
-
accountNameExistsInConfig,
|
|
18
|
-
getConfig,
|
|
19
|
-
writeConfig,
|
|
20
|
-
updateAccountConfig,
|
|
21
|
-
getAccountId,
|
|
22
|
-
} = require('@hubspot/local-dev-lib/config');
|
|
10
|
+
const { getConfig, getAccountId } = require('@hubspot/local-dev-lib/config');
|
|
23
11
|
const CliProgressMultibarManager = require('./CliProgressMultibarManager');
|
|
24
12
|
const { promptUser } = require('./prompts/promptUtils');
|
|
25
13
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
26
14
|
const {
|
|
27
|
-
|
|
28
|
-
} = require('
|
|
29
|
-
const {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
15
|
+
HUBSPOT_ACCOUNT_TYPES,
|
|
16
|
+
} = require('@hubspot/local-dev-lib/constants/config');
|
|
17
|
+
const {
|
|
18
|
+
STANDARD_SANDBOX_TYPE,
|
|
19
|
+
DEVELOPER_SANDBOX_TYPE,
|
|
20
|
+
DEVELOPER_SANDBOX,
|
|
21
|
+
STANDARD_SANDBOX,
|
|
22
|
+
} = require('./constants');
|
|
33
23
|
|
|
34
24
|
const syncTypes = {
|
|
35
25
|
OBJECT_RECORDS: 'object-records',
|
|
36
26
|
};
|
|
37
27
|
|
|
38
28
|
const sandboxTypeMap = {
|
|
39
|
-
DEV:
|
|
40
|
-
dev:
|
|
41
|
-
DEVELOPER:
|
|
42
|
-
developer:
|
|
43
|
-
DEVELOPMENT:
|
|
44
|
-
development:
|
|
45
|
-
STANDARD:
|
|
46
|
-
standard:
|
|
29
|
+
DEV: DEVELOPER_SANDBOX_TYPE,
|
|
30
|
+
dev: DEVELOPER_SANDBOX_TYPE,
|
|
31
|
+
DEVELOPER: DEVELOPER_SANDBOX_TYPE,
|
|
32
|
+
developer: DEVELOPER_SANDBOX_TYPE,
|
|
33
|
+
DEVELOPMENT: DEVELOPER_SANDBOX_TYPE,
|
|
34
|
+
development: DEVELOPER_SANDBOX_TYPE,
|
|
35
|
+
STANDARD: STANDARD_SANDBOX_TYPE,
|
|
36
|
+
standard: STANDARD_SANDBOX_TYPE,
|
|
47
37
|
};
|
|
48
38
|
|
|
49
39
|
const sandboxApiTypeMap = {
|
|
@@ -51,23 +41,26 @@ const sandboxApiTypeMap = {
|
|
|
51
41
|
developer: 2,
|
|
52
42
|
};
|
|
53
43
|
|
|
54
|
-
const getSandboxTypeAsString =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
44
|
+
const getSandboxTypeAsString = accountType => {
|
|
45
|
+
if (
|
|
46
|
+
accountType === HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX ||
|
|
47
|
+
accountType === DEVELOPER_SANDBOX // remove line once sandboxAccountType is removed
|
|
48
|
+
) {
|
|
49
|
+
return 'development'; // Only place we're using this specific name
|
|
50
|
+
}
|
|
51
|
+
return STANDARD_SANDBOX_TYPE;
|
|
52
|
+
};
|
|
59
53
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
config.sandboxAccountType
|
|
54
|
+
const getSandboxName = config =>
|
|
55
|
+
`[${getSandboxTypeAsString(
|
|
56
|
+
config.accountType || config.sandboxAccountType
|
|
63
57
|
)} sandbox] `;
|
|
64
58
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
59
|
+
const isSandbox = config =>
|
|
60
|
+
config.accountType
|
|
61
|
+
? config.accountType === HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX ||
|
|
62
|
+
config.accountType === HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX
|
|
63
|
+
: config.sandboxAccountType && config.sandboxAccountType !== null;
|
|
71
64
|
|
|
72
65
|
function getHasSandboxesByType(parentAccountConfig, type) {
|
|
73
66
|
const config = getConfig();
|
|
@@ -153,13 +146,13 @@ const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
|
153
146
|
if (!usage) {
|
|
154
147
|
throw new Error('Unable to fetch sandbox usage limits. Please try again.');
|
|
155
148
|
}
|
|
156
|
-
if (sandboxType ===
|
|
157
|
-
if (usage[
|
|
158
|
-
const devSandboxLimit = usage[
|
|
149
|
+
if (sandboxType === DEVELOPER_SANDBOX_TYPE) {
|
|
150
|
+
if (usage[DEVELOPER_SANDBOX].available === 0) {
|
|
151
|
+
const devSandboxLimit = usage[DEVELOPER_SANDBOX].limit;
|
|
159
152
|
const plural = devSandboxLimit !== 1;
|
|
160
153
|
const hasDevelopmentSandboxes = getHasSandboxesByType(
|
|
161
154
|
accountConfig,
|
|
162
|
-
|
|
155
|
+
DEVELOPER_SANDBOX_TYPE
|
|
163
156
|
);
|
|
164
157
|
if (hasDevelopmentSandboxes) {
|
|
165
158
|
throw new Error(
|
|
@@ -190,13 +183,13 @@ const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
|
190
183
|
}
|
|
191
184
|
}
|
|
192
185
|
}
|
|
193
|
-
if (sandboxType ===
|
|
194
|
-
if (usage[
|
|
195
|
-
const standardSandboxLimit = usage[
|
|
186
|
+
if (sandboxType === STANDARD_SANDBOX_TYPE) {
|
|
187
|
+
if (usage[STANDARD_SANDBOX].available === 0) {
|
|
188
|
+
const standardSandboxLimit = usage[STANDARD_SANDBOX].limit;
|
|
196
189
|
const plural = standardSandboxLimit !== 1;
|
|
197
190
|
const hasStandardSandboxes = getHasSandboxesByType(
|
|
198
191
|
accountConfig,
|
|
199
|
-
|
|
192
|
+
STANDARD_SANDBOX_TYPE
|
|
200
193
|
);
|
|
201
194
|
if (hasStandardSandboxes) {
|
|
202
195
|
throw new Error(
|
|
@@ -229,78 +222,6 @@ const validateSandboxUsageLimits = async (accountConfig, sandboxType, env) => {
|
|
|
229
222
|
}
|
|
230
223
|
};
|
|
231
224
|
|
|
232
|
-
/**
|
|
233
|
-
* @param {String} env - Environment (QA/Prod)
|
|
234
|
-
* @param {Object} result - Sandbox instance returned from API
|
|
235
|
-
* @param {Boolean} force - Force flag to skip prompt
|
|
236
|
-
* @returns {String} validName saved into config
|
|
237
|
-
*/
|
|
238
|
-
const saveSandboxToConfig = async (env, result, force = false) => {
|
|
239
|
-
let personalAccessKey = result.personalAccessKey;
|
|
240
|
-
if (!personalAccessKey) {
|
|
241
|
-
const configData = await personalAccessKeyPrompt({
|
|
242
|
-
env,
|
|
243
|
-
account: result.sandbox.sandboxHubId,
|
|
244
|
-
});
|
|
245
|
-
personalAccessKey = configData.personalAccessKey;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
let updatedConfig;
|
|
249
|
-
|
|
250
|
-
try {
|
|
251
|
-
const token = await getAccessToken(personalAccessKey, env);
|
|
252
|
-
updatedConfig = await updateConfigWithAccessToken(
|
|
253
|
-
token,
|
|
254
|
-
personalAccessKey,
|
|
255
|
-
env
|
|
256
|
-
);
|
|
257
|
-
} catch (e) {
|
|
258
|
-
logErrorInstance(e);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
if (!updatedConfig) {
|
|
262
|
-
throw new Error('Failed to update config with personal access key.');
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
let validName = updatedConfig.name;
|
|
266
|
-
if (!updatedConfig.name) {
|
|
267
|
-
const nameForConfig = result.sandbox.name
|
|
268
|
-
.toLowerCase()
|
|
269
|
-
.split(' ')
|
|
270
|
-
.join('-');
|
|
271
|
-
validName = nameForConfig;
|
|
272
|
-
const invalidAccountName = accountNameExistsInConfig(nameForConfig);
|
|
273
|
-
if (invalidAccountName) {
|
|
274
|
-
if (!force) {
|
|
275
|
-
logger.log('');
|
|
276
|
-
logger.warn(
|
|
277
|
-
i18n(
|
|
278
|
-
`cli.lib.prompts.enterAccountNamePrompt.errors.accountNameExists`,
|
|
279
|
-
{ name: nameForConfig }
|
|
280
|
-
)
|
|
281
|
-
);
|
|
282
|
-
const { name: promptName } = await enterAccountNamePrompt(
|
|
283
|
-
nameForConfig + `_${result.sandbox.sandboxHubId}`
|
|
284
|
-
);
|
|
285
|
-
validName = promptName;
|
|
286
|
-
} else {
|
|
287
|
-
// Basic invalid name handling when force flag is passed
|
|
288
|
-
validName = nameForConfig + `_${result.sandbox.sandboxHubId}`;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
updateAccountConfig({
|
|
293
|
-
...updatedConfig,
|
|
294
|
-
environment: updatedConfig.env,
|
|
295
|
-
tokenInfo: updatedConfig.auth.tokenInfo,
|
|
296
|
-
name: validName,
|
|
297
|
-
});
|
|
298
|
-
writeConfig();
|
|
299
|
-
|
|
300
|
-
logger.log('');
|
|
301
|
-
return validName;
|
|
302
|
-
};
|
|
303
|
-
|
|
304
225
|
const ACTIVE_TASK_POLL_INTERVAL = 1000;
|
|
305
226
|
|
|
306
227
|
const isTaskComplete = task => {
|
|
@@ -439,15 +360,12 @@ function pollSyncTaskStatus(
|
|
|
439
360
|
}
|
|
440
361
|
|
|
441
362
|
module.exports = {
|
|
442
|
-
STANDARD_SANDBOX,
|
|
443
|
-
DEVELOPER_SANDBOX,
|
|
444
363
|
sandboxTypeMap,
|
|
445
364
|
sandboxApiTypeMap,
|
|
446
365
|
syncTypes,
|
|
447
366
|
isSandbox,
|
|
367
|
+
getSandboxName,
|
|
448
368
|
getSandboxTypeAsString,
|
|
449
|
-
getAccountName,
|
|
450
|
-
saveSandboxToConfig,
|
|
451
369
|
getHasSandboxesByType,
|
|
452
370
|
getSandboxLimit,
|
|
453
371
|
validateSandboxUsageLimits,
|
package/lib/ui.js
CHANGED
|
@@ -4,6 +4,11 @@ const supportsColor = require('../lib/supportsColor');
|
|
|
4
4
|
const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
|
|
5
5
|
const { i18n } = require('./lang');
|
|
6
6
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
7
|
+
const { isSandbox, getSandboxName } = require('./sandboxes');
|
|
8
|
+
const {
|
|
9
|
+
isDeveloperTestAccount,
|
|
10
|
+
DEV_TEST_ACCOUNT_STRING,
|
|
11
|
+
} = require('./developerTestAccounts');
|
|
7
12
|
|
|
8
13
|
const UI_COLORS = {
|
|
9
14
|
SORBET: '#FF8F59',
|
|
@@ -65,16 +70,22 @@ const uiLink = (linkText, url) => {
|
|
|
65
70
|
};
|
|
66
71
|
|
|
67
72
|
/**
|
|
68
|
-
* Returns formatted account name and ID
|
|
73
|
+
* Returns formatted account name, account type (if applicable), and ID
|
|
69
74
|
*
|
|
70
75
|
* @param {number} accountId
|
|
76
|
+
* @param {boolean} bold
|
|
71
77
|
* @returns {string}
|
|
72
78
|
*/
|
|
73
|
-
const uiAccountDescription = accountId => {
|
|
79
|
+
const uiAccountDescription = (accountId, bold = true) => {
|
|
74
80
|
const account = getAccountConfig(accountId);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
let accountTypeString = '';
|
|
82
|
+
if (isSandbox(account)) {
|
|
83
|
+
accountTypeString = getSandboxName(account);
|
|
84
|
+
} else if (isDeveloperTestAccount(account)) {
|
|
85
|
+
accountTypeString = `[${DEV_TEST_ACCOUNT_STRING}] `;
|
|
86
|
+
}
|
|
87
|
+
const message = `${account.name} ${accountTypeString}(${account.portalId})`;
|
|
88
|
+
return bold ? chalk.bold(message) : message;
|
|
78
89
|
};
|
|
79
90
|
|
|
80
91
|
const uiInfoSection = (title, logContent) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "5.1.4-beta.
|
|
3
|
+
"version": "5.1.4-beta.1",
|
|
4
4
|
"description": "CLI for working with HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@hubspot/cli-lib": "^9.0.0",
|
|
12
|
-
"@hubspot/local-dev-lib": "^0.3.
|
|
13
|
-
"@hubspot/serverless-dev-runtime": "5.1.4-beta.
|
|
12
|
+
"@hubspot/local-dev-lib": "^0.3.4",
|
|
13
|
+
"@hubspot/serverless-dev-runtime": "5.1.4-beta.1",
|
|
14
14
|
"@hubspot/ui-extensions-dev-server": "0.8.9",
|
|
15
15
|
"archiver": "^5.3.0",
|
|
16
16
|
"chalk": "^4.1.2",
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"publishConfig": {
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "8c66f7e80438c191d2e5148d9cc08e64dca7cf6e"
|
|
49
49
|
}
|