@hubspot/cli 7.0.1-experimental.0 → 7.0.2-beta.0
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/README.md +3 -2
- package/bin/cli.js +37 -5
- package/commands/account/info.d.ts +7 -0
- package/commands/account/info.js +28 -25
- package/commands/account/remove.js +4 -4
- package/commands/account/use.js +3 -3
- package/commands/auth.js +3 -3
- package/commands/customObject/create.js +4 -1
- package/commands/function/deploy.js +1 -1
- package/commands/hubdb/create.js +2 -2
- package/commands/init.js +1 -1
- package/commands/logs.js +1 -7
- package/commands/project/cloneApp.js +1 -1
- package/commands/project/create.js +6 -0
- package/commands/project/deploy.js +1 -1
- package/commands/project/dev.js +4 -3
- package/commands/project/installDeps.js +2 -4
- package/commands/project/migrateApp.js +1 -1
- package/commands/project/upload.js +5 -10
- package/commands/project/watch.js +4 -4
- package/commands/sandbox/create.js +7 -18
- package/commands/sandbox/delete.js +6 -10
- package/commands/theme/preview.js +3 -2
- package/lang/en.lyaml +15 -6
- package/lib/DevServerManager.d.ts +40 -1
- package/lib/DevServerManager.js +39 -30
- package/lib/LocalDevManager.d.ts +58 -1
- package/lib/LocalDevManager.js +162 -121
- package/lib/buildAccount.d.ts +12 -0
- package/lib/buildAccount.js +110 -95
- package/lib/commonOpts.d.ts +4 -15
- package/lib/commonOpts.js +2 -28
- package/lib/constants.d.ts +1 -7
- package/lib/constants.js +2 -8
- package/lib/dependencyManagement.d.ts +9 -4
- package/lib/dependencyManagement.js +45 -49
- package/lib/developerTestAccounts.d.ts +1 -0
- package/lib/developerTestAccounts.js +1 -0
- package/lib/errorHandlers/index.js +5 -2
- package/lib/localDev.d.ts +17 -1
- package/lib/localDev.js +203 -203
- package/lib/polling.d.ts +13 -5
- package/lib/polling.js +21 -7
- package/lib/projects/buildAndDeploy.d.ts +1 -7
- package/lib/projects/buildAndDeploy.js +3 -3
- package/lib/projects/index.js +9 -4
- package/lib/projects/structure.d.ts +5 -71
- package/lib/projects/structure.js +27 -10
- package/lib/projects/upload.d.ts +4 -3
- package/lib/projects/upload.js +7 -30
- package/lib/projects/watch.d.ts +3 -0
- package/lib/projects/watch.js +73 -70
- package/lib/prompts/createProjectPrompt.js +8 -1
- package/lib/prompts/installPublicAppPrompt.d.ts +1 -1
- package/lib/prompts/personalAccessKeyPrompt.d.ts +1 -1
- package/lib/prompts/projectDevTargetAccountPrompt.d.ts +2 -2
- package/lib/sandboxSync.d.ts +4 -1
- package/lib/sandboxSync.js +67 -68
- package/lib/sandboxes.d.ts +20 -1
- package/lib/sandboxes.js +77 -175
- package/lib/serverlessLogs.d.ts +4 -1
- package/lib/serverlessLogs.js +64 -60
- package/lib/ui/serverlessFunctionLogs.d.ts +8 -0
- package/lib/ui/serverlessFunctionLogs.js +1 -3
- package/lib/validation.d.ts +2 -0
- package/lib/validation.js +5 -8
- package/package.json +9 -9
- package/types/Projects.d.ts +74 -0
- package/types/Projects.js +7 -0
- package/types/Sandboxes.d.ts +3 -0
- package/types/Sandboxes.js +2 -0
- package/types/Yargs.d.ts +14 -0
- package/types/Yargs.js +2 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hubspot/cli
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@hubspot/cli) [](https://www.npmjs.com/package/@hubspot/cli) [](https://www.npmjs.com/package/@hubspot/cli?activeTab=versions)
|
|
4
4
|
|
|
5
5
|
A CLI for HubSpot developers to enable local development and automation. [Learn more about building on HubSpot](https://developers.hubspot.com).
|
|
6
6
|
|
|
@@ -58,14 +58,15 @@ There are two ways that the tools can authenticate with HubSpot.
|
|
|
58
58
|
3. Select `OAuth2` and follow the steps
|
|
59
59
|
|
|
60
60
|
_**Note:** The Account ID used should be the Test Account ID (not the developer app ID). Client ID and Client Secret are from the developer app._
|
|
61
|
+
|
|
61
62
|
### Exit Codes
|
|
62
63
|
|
|
63
64
|
The CLI will exit with one of the following exit codes:
|
|
65
|
+
|
|
64
66
|
- `0`: A successful run
|
|
65
67
|
- `1`: There was a config problem or an internal error
|
|
66
68
|
- `2`: There are warnings or validation issues
|
|
67
69
|
|
|
68
|
-
|
|
69
70
|
## Changelog
|
|
70
71
|
|
|
71
72
|
The best way to stay up to date is to check out the [Github Releases](https://github.com/HubSpot/hubspot-cli/releases) and also follow our [developer changelog posts](https://developers.hubspot.com/changelog) for an easier to read breakdown of major changes.
|
package/bin/cli.js
CHANGED
|
@@ -5,16 +5,16 @@ const updateNotifier = require('update-notifier');
|
|
|
5
5
|
const chalk = require('chalk');
|
|
6
6
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
7
7
|
const { addUserAgentHeader } = require('@hubspot/local-dev-lib/http');
|
|
8
|
-
const { loadConfig, configFileExists, getConfigPath, validateConfig, } = require('@hubspot/local-dev-lib/config');
|
|
8
|
+
const { loadConfig, getAccountId, configFileExists, getConfigPath, validateConfig, } = require('@hubspot/local-dev-lib/config');
|
|
9
9
|
const { logError } = require('../lib/errorHandlers/index');
|
|
10
|
-
const { setLogLevel, getCommandName
|
|
10
|
+
const { setLogLevel, getCommandName } = require('../lib/commonOpts');
|
|
11
11
|
const { validateAccount } = require('../lib/validation');
|
|
12
12
|
const { trackHelpUsage, trackConvertFieldsUsage, } = require('../lib/usageTracking');
|
|
13
13
|
const { getIsInProject } = require('../lib/projects');
|
|
14
14
|
const pkg = require('../package.json');
|
|
15
15
|
const { i18n } = require('../lib/lang');
|
|
16
16
|
const { EXIT_CODES } = require('../lib/enums/exitCodes');
|
|
17
|
-
const { UI_COLORS, uiCommandReference } = require('../lib/ui');
|
|
17
|
+
const { UI_COLORS, uiCommandReference, uiDeprecatedTag } = require('../lib/ui');
|
|
18
18
|
const { checkAndWarnGitInclusion } = require('../lib/ui/git');
|
|
19
19
|
const removeCommand = require('../commands/remove');
|
|
20
20
|
const initCommand = require('../commands/init');
|
|
@@ -141,6 +141,32 @@ const SKIP_CONFIG_VALIDATION = {
|
|
|
141
141
|
init: { target: true },
|
|
142
142
|
auth: { target: true },
|
|
143
143
|
};
|
|
144
|
+
const handleDeprecatedEnvVariables = options => {
|
|
145
|
+
// HUBSPOT_PORTAL_ID is deprecated, but we'll still support it for now
|
|
146
|
+
// The HubSpot GH Deploy Action still uses HUBSPOT_PORTAL_ID
|
|
147
|
+
if (options.useEnv &&
|
|
148
|
+
process.env.HUBSPOT_PORTAL_ID &&
|
|
149
|
+
!process.env.HUBSPOT_ACCOUNT_ID) {
|
|
150
|
+
uiDeprecatedTag(i18n(`${i18nKey}.handleDeprecatedEnvVariables.portalEnvVarDeprecated`, {
|
|
151
|
+
configPath: getConfigPath(),
|
|
152
|
+
}));
|
|
153
|
+
process.env.HUBSPOT_ACCOUNT_ID = process.env.HUBSPOT_PORTAL_ID;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Auto-injects the derivedAccountId flag into all commands
|
|
158
|
+
*/
|
|
159
|
+
const injectAccountIdMiddleware = async (options) => {
|
|
160
|
+
const { account } = options;
|
|
161
|
+
// Preserves the original --account flag for certain commands.
|
|
162
|
+
options.providedAccountId = account;
|
|
163
|
+
if (options.useEnv && process.env.HUBSPOT_ACCOUNT_ID) {
|
|
164
|
+
options.derivedAccountId = parseInt(process.env.HUBSPOT_ACCOUNT_ID, 10);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
options.derivedAccountId = getAccountId(account);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
144
170
|
const loadConfigMiddleware = async (options) => {
|
|
145
171
|
// Skip this when no command is provided
|
|
146
172
|
if (!options._.length) {
|
|
@@ -158,9 +184,14 @@ const loadConfigMiddleware = async (options) => {
|
|
|
158
184
|
}));
|
|
159
185
|
process.exit(EXIT_CODES.ERROR);
|
|
160
186
|
}
|
|
161
|
-
else if (!options
|
|
187
|
+
else if (!isTargetedCommand(options, { init: { target: true } })) {
|
|
162
188
|
const { config: configPath } = options;
|
|
163
|
-
loadConfig(configPath, options);
|
|
189
|
+
const config = loadConfig(configPath, options);
|
|
190
|
+
// We don't run validateConfig() for auth because users should be able to run it when
|
|
191
|
+
// no accounts are configured, but we still want to exit if the config file is not found
|
|
192
|
+
if (isTargetedCommand(options, { auth: { target: true } }) && !config) {
|
|
193
|
+
process.exit(EXIT_CODES.ERROR);
|
|
194
|
+
}
|
|
164
195
|
}
|
|
165
196
|
maybeValidateConfig();
|
|
166
197
|
};
|
|
@@ -213,6 +244,7 @@ const argv = yargs
|
|
|
213
244
|
.middleware([
|
|
214
245
|
setLogLevel,
|
|
215
246
|
setRequestHeaders,
|
|
247
|
+
handleDeprecatedEnvVariables,
|
|
216
248
|
loadConfigMiddleware,
|
|
217
249
|
injectAccountIdMiddleware,
|
|
218
250
|
checkAndWarnGitInclusionMiddleware,
|
|
@@ -1 +1,8 @@
|
|
|
1
|
+
import { Argv, ArgumentsCamelCase } from 'yargs';
|
|
2
|
+
import { CommonArgs, ConfigArgs } from '../../types/Yargs';
|
|
3
|
+
export declare const describe: string;
|
|
4
|
+
export declare const command = "info [account]";
|
|
5
|
+
type AccountInfoArgs = CommonArgs & ConfigArgs;
|
|
6
|
+
export declare function handler(args: ArgumentsCamelCase<AccountInfoArgs>): Promise<void>;
|
|
7
|
+
export declare function builder(yargs: Argv): Argv<AccountInfoArgs>;
|
|
1
8
|
export {};
|
package/commands/account/info.js
CHANGED
|
@@ -1,38 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
3
|
+
exports.command = exports.describe = void 0;
|
|
4
|
+
exports.handler = handler;
|
|
5
|
+
exports.builder = builder;
|
|
6
|
+
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
7
|
+
const config_1 = require("@hubspot/local-dev-lib/config");
|
|
8
|
+
const personalAccessKey_1 = require("@hubspot/local-dev-lib/personalAccessKey");
|
|
9
|
+
const commonOpts_1 = require("../../lib/commonOpts");
|
|
10
|
+
const lang_1 = require("../../lib/lang");
|
|
11
|
+
const table_1 = require("../../lib/ui/table");
|
|
10
12
|
const i18nKey = 'commands.account.subcommands.info';
|
|
11
|
-
exports.describe = i18n(`${i18nKey}.describe`);
|
|
13
|
+
exports.describe = (0, lang_1.i18n)(`${i18nKey}.describe`);
|
|
12
14
|
exports.command = 'info [account]';
|
|
13
|
-
|
|
14
|
-
const { derivedAccountId } =
|
|
15
|
-
const config = getAccountConfig(derivedAccountId);
|
|
15
|
+
async function handler(args) {
|
|
16
|
+
const { derivedAccountId } = args;
|
|
17
|
+
const config = (0, config_1.getAccountConfig)(derivedAccountId);
|
|
16
18
|
// check if the provided account is using a personal access key, if not, show an error
|
|
17
19
|
if (config && config.authType === 'personalaccesskey') {
|
|
18
20
|
const { name, personalAccessKey, env } = config;
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
logger.log(i18n(`${i18nKey}.
|
|
23
|
-
logger.log(i18n(`${i18nKey}.
|
|
24
|
-
logger.log(
|
|
21
|
+
let scopeGroups = [];
|
|
22
|
+
const response = await (0, personalAccessKey_1.getAccessToken)(personalAccessKey, env, derivedAccountId);
|
|
23
|
+
scopeGroups = response.scopeGroups.map(s => [s]);
|
|
24
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.name`, { name: name }));
|
|
25
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.accountId`, { accountId: derivedAccountId }));
|
|
26
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.scopeGroups`));
|
|
27
|
+
logger_1.logger.log((0, table_1.getTableContents)(scopeGroups, { border: { bodyLeft: ' ' } }));
|
|
25
28
|
}
|
|
26
29
|
else {
|
|
27
|
-
logger.log(i18n(`${i18nKey}.errors.notUsingPersonalAccessKey`));
|
|
30
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.errors.notUsingPersonalAccessKey`));
|
|
28
31
|
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
addConfigOptions(yargs);
|
|
32
|
+
}
|
|
33
|
+
function builder(yargs) {
|
|
34
|
+
(0, commonOpts_1.addConfigOptions)(yargs);
|
|
32
35
|
yargs.example([
|
|
33
|
-
['$0 accounts info', i18n(`${i18nKey}.examples.default`)],
|
|
34
|
-
['$0 accounts info MyAccount', i18n(`${i18nKey}.examples.nameBased`)],
|
|
35
|
-
['$0 accounts info 1234567', i18n(`${i18nKey}.examples.idBased`)],
|
|
36
|
+
['$0 accounts info', (0, lang_1.i18n)(`${i18nKey}.examples.default`)],
|
|
37
|
+
['$0 accounts info MyAccount', (0, lang_1.i18n)(`${i18nKey}.examples.nameBased`)],
|
|
38
|
+
['$0 accounts info 1234567', (0, lang_1.i18n)(`${i18nKey}.examples.idBased`)],
|
|
36
39
|
]);
|
|
37
40
|
return yargs;
|
|
38
|
-
}
|
|
41
|
+
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
// @ts-nocheck
|
|
4
4
|
const { addConfigOptions } = require('../../lib/commonOpts');
|
|
5
5
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
6
|
-
const { loadConfig, getConfigPath, deleteAccount, getConfigDefaultAccount, getAccountId
|
|
6
|
+
const { loadConfig, getConfigPath, deleteAccount, getConfigDefaultAccount, getAccountId, updateDefaultAccount, } = require('@hubspot/local-dev-lib/config');
|
|
7
7
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
8
8
|
const { i18n } = require('../../lib/lang');
|
|
9
9
|
const { selectAccountFromConfig } = require('../../lib/prompts/accountsPrompt');
|
|
@@ -13,16 +13,16 @@ exports.describe = i18n(`${i18nKey}.describe`);
|
|
|
13
13
|
exports.handler = async (options) => {
|
|
14
14
|
const { account } = options;
|
|
15
15
|
let accountToRemove = account;
|
|
16
|
-
if (accountToRemove && !
|
|
16
|
+
if (accountToRemove && !getAccountId(accountToRemove)) {
|
|
17
17
|
logger.error(i18n(`${i18nKey}.errors.accountNotFound`, {
|
|
18
18
|
specifiedAccount: accountToRemove,
|
|
19
19
|
configPath: getConfigPath(),
|
|
20
20
|
}));
|
|
21
21
|
}
|
|
22
|
-
if (!accountToRemove || !
|
|
22
|
+
if (!accountToRemove || !getAccountId(accountToRemove)) {
|
|
23
23
|
accountToRemove = await selectAccountFromConfig(i18n(`${i18nKey}.prompts.selectAccountToRemove`));
|
|
24
24
|
}
|
|
25
|
-
trackCommandUsage('accounts-remove', null,
|
|
25
|
+
trackCommandUsage('accounts-remove', null, getAccountId(accountToRemove));
|
|
26
26
|
const currentDefaultAccount = getConfigDefaultAccount();
|
|
27
27
|
await deleteAccount(accountToRemove);
|
|
28
28
|
logger.success(i18n(`${i18nKey}.success.accountRemoved`, {
|
package/commands/account/use.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
// @ts-nocheck
|
|
4
4
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
5
|
-
const { getConfigPath, updateDefaultAccount, getAccountId
|
|
5
|
+
const { getConfigPath, updateDefaultAccount, getAccountId, } = require('@hubspot/local-dev-lib/config');
|
|
6
6
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
7
7
|
const { i18n } = require('../../lib/lang');
|
|
8
8
|
const { selectAccountFromConfig } = require('../../lib/prompts/accountsPrompt');
|
|
@@ -14,14 +14,14 @@ exports.handler = async (options) => {
|
|
|
14
14
|
if (!newDefaultAccount) {
|
|
15
15
|
newDefaultAccount = await selectAccountFromConfig();
|
|
16
16
|
}
|
|
17
|
-
else if (!
|
|
17
|
+
else if (!getAccountId(newDefaultAccount)) {
|
|
18
18
|
logger.error(i18n(`${i18nKey}.errors.accountNotFound`, {
|
|
19
19
|
specifiedAccount: newDefaultAccount,
|
|
20
20
|
configPath: getConfigPath(),
|
|
21
21
|
}));
|
|
22
22
|
newDefaultAccount = await selectAccountFromConfig();
|
|
23
23
|
}
|
|
24
|
-
trackCommandUsage('accounts-use', null,
|
|
24
|
+
trackCommandUsage('accounts-use', null, getAccountId(newDefaultAccount));
|
|
25
25
|
updateDefaultAccount(newDefaultAccount);
|
|
26
26
|
return logger.success(i18n(`${i18nKey}.success.defaultAccountUpdated`, {
|
|
27
27
|
accountName: newDefaultAccount,
|
package/commands/auth.js
CHANGED
|
@@ -8,13 +8,13 @@ const { ENVIRONMENTS, } = require('@hubspot/local-dev-lib/constants/environments
|
|
|
8
8
|
const { DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME, } = require('@hubspot/local-dev-lib/constants/config');
|
|
9
9
|
const { i18n } = require('../lib/lang');
|
|
10
10
|
const { getAccessToken, updateConfigWithAccessToken, } = require('@hubspot/local-dev-lib/personalAccessKey');
|
|
11
|
-
const { updateAccountConfig, writeConfig, getConfigPath, loadConfig, getConfigDefaultAccount, } = require('@hubspot/local-dev-lib/config');
|
|
11
|
+
const { updateAccountConfig, writeConfig, getConfigPath, loadConfig, getConfigDefaultAccount, getAccountId, } = require('@hubspot/local-dev-lib/config');
|
|
12
12
|
const { commaSeparatedValues, toKebabCase, } = require('@hubspot/local-dev-lib/text');
|
|
13
13
|
const { promptUser } = require('../lib/prompts/promptUtils');
|
|
14
14
|
const { personalAccessKeyPrompt, OAUTH_FLOW, } = require('../lib/prompts/personalAccessKeyPrompt');
|
|
15
15
|
const { cliAccountNamePrompt } = require('../lib/prompts/accountNamePrompt');
|
|
16
16
|
const { setAsDefaultAccountPrompt, } = require('../lib/prompts/setAsDefaultAccountPrompt');
|
|
17
|
-
const { addConfigOptions, setLogLevel,
|
|
17
|
+
const { addConfigOptions, setLogLevel, addTestingOptions, addGlobalOptions, } = require('../lib/commonOpts');
|
|
18
18
|
const { trackAuthAction, trackCommandUsage } = require('../lib/usageTracking');
|
|
19
19
|
const { authenticateWithOauth } = require('../lib/oauth');
|
|
20
20
|
const { EXIT_CODES } = require('../lib/enums/exitCodes');
|
|
@@ -129,7 +129,7 @@ exports.handler = async (options) => {
|
|
|
129
129
|
'accountOption',
|
|
130
130
|
'accountsListCommand',
|
|
131
131
|
]);
|
|
132
|
-
const accountId = getAccountId(
|
|
132
|
+
const accountId = getAccountId(accountName);
|
|
133
133
|
await trackAuthAction('auth', authType, TRACKING_STATUS.COMPLETE, accountId);
|
|
134
134
|
process.exit(EXIT_CODES.SUCCESS);
|
|
135
135
|
};
|
|
@@ -16,7 +16,11 @@ exports.describe = i18n(`${i18nKey}.describe`);
|
|
|
16
16
|
exports.handler = async (options) => {
|
|
17
17
|
const { path, name: providedName, derivedAccountId } = options;
|
|
18
18
|
let definitionPath = path;
|
|
19
|
+
let name = providedName;
|
|
19
20
|
trackCommandUsage('custom-object-batch-create', null, derivedAccountId);
|
|
21
|
+
if (!name) {
|
|
22
|
+
name = await (0, promptUtils_1.inputPrompt)(i18n(`${i18nKey}.inputName`));
|
|
23
|
+
}
|
|
20
24
|
if (!definitionPath) {
|
|
21
25
|
definitionPath = await (0, promptUtils_1.inputPrompt)(i18n(`${i18nKey}.inputPath`));
|
|
22
26
|
}
|
|
@@ -25,7 +29,6 @@ exports.handler = async (options) => {
|
|
|
25
29
|
if (!objectJson) {
|
|
26
30
|
process.exit(EXIT_CODES.ERROR);
|
|
27
31
|
}
|
|
28
|
-
const name = providedName || (await (0, promptUtils_1.inputPrompt)(i18n(`${i18nKey}.inputSchema`)));
|
|
29
32
|
try {
|
|
30
33
|
await batchCreateObjects(derivedAccountId, name, objectJson);
|
|
31
34
|
logger.success(i18n(`${i18nKey}.success.objectsCreated`));
|
|
@@ -38,7 +38,7 @@ exports.handler = async (options) => {
|
|
|
38
38
|
});
|
|
39
39
|
try {
|
|
40
40
|
const { data: buildId } = await buildPackage(derivedAccountId, functionPath);
|
|
41
|
-
const successResp = await poll(getBuildStatus
|
|
41
|
+
const successResp = await poll(() => getBuildStatus(derivedAccountId, buildId));
|
|
42
42
|
const buildTimeSeconds = (successResp.buildTime / 1000).toFixed(2);
|
|
43
43
|
SpinniesManager.succeed('loading');
|
|
44
44
|
await outputBuildLog(successResp.cdnUrl);
|
package/commands/hubdb/create.js
CHANGED
|
@@ -42,9 +42,9 @@ exports.handler = async (options) => {
|
|
|
42
42
|
trackCommandUsage('hubdb-create', null, derivedAccountId);
|
|
43
43
|
let filePath;
|
|
44
44
|
try {
|
|
45
|
-
const
|
|
45
|
+
const filePath = 'path' in options
|
|
46
46
|
? path.resolve(getCwd(), options.path)
|
|
47
|
-
: await selectPathPrompt(options);
|
|
47
|
+
: path.resolve(getCwd(), (await selectPathPrompt(options)).path);
|
|
48
48
|
if (!checkAndConvertToJson(filePath)) {
|
|
49
49
|
process.exit(EXIT_CODES.ERROR);
|
|
50
50
|
}
|
package/commands/init.js
CHANGED
|
@@ -67,7 +67,7 @@ exports.describe = i18n(`${i18nKey}.describe`, {
|
|
|
67
67
|
configName: DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
|
|
68
68
|
});
|
|
69
69
|
exports.handler = async (options) => {
|
|
70
|
-
const {
|
|
70
|
+
const { authType: authTypeFlagValue, c: configFlagValue, providedAccountId, disableTracking, useHiddenConfig, } = options;
|
|
71
71
|
const authType = (authTypeFlagValue && authTypeFlagValue.toLowerCase()) ||
|
|
72
72
|
PERSONAL_ACCESS_KEY_AUTH_METHOD.value;
|
|
73
73
|
const configPath = (configFlagValue && path.join(getCwd(), configFlagValue)) ||
|
package/commands/logs.js
CHANGED
|
@@ -44,13 +44,7 @@ const endpointLog = async (accountId, functionPath, options) => {
|
|
|
44
44
|
handleLogsError(e, accountId, functionPath);
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
|
-
await tailLogs(
|
|
48
|
-
accountId,
|
|
49
|
-
compact,
|
|
50
|
-
tailCall,
|
|
51
|
-
fetchLatest,
|
|
52
|
-
name: functionPath,
|
|
53
|
-
});
|
|
47
|
+
await tailLogs(accountId, functionPath, fetchLatest, tailCall, compact);
|
|
54
48
|
}
|
|
55
49
|
else if (latest) {
|
|
56
50
|
try {
|
|
@@ -68,7 +68,7 @@ exports.handler = async (options) => {
|
|
|
68
68
|
text: i18n(`${i18nKey}.cloneStatus.inProgress`),
|
|
69
69
|
});
|
|
70
70
|
const { data: { exportId }, } = await cloneApp(derivedAccountId, appId);
|
|
71
|
-
const { status } = await poll(checkCloneStatus
|
|
71
|
+
const { status } = await poll(() => checkCloneStatus(derivedAccountId, exportId));
|
|
72
72
|
if (status === 'SUCCESS') {
|
|
73
73
|
// Ensure correct project folder structure exists
|
|
74
74
|
const baseDestPath = path.resolve(getCwd(), projectDest);
|
|
@@ -56,6 +56,12 @@ exports.builder = yargs => {
|
|
|
56
56
|
},
|
|
57
57
|
});
|
|
58
58
|
yargs.example([['$0 project create', i18n(`${i18nKey}.examples.default`)]]);
|
|
59
|
+
yargs.example([
|
|
60
|
+
[
|
|
61
|
+
'$0 project create --template-source HubSpot/ui-extensions-examples',
|
|
62
|
+
i18n(`${i18nKey}.examples.templateSource`),
|
|
63
|
+
],
|
|
64
|
+
]);
|
|
59
65
|
addConfigOptions(yargs);
|
|
60
66
|
addAccountOptions(yargs);
|
|
61
67
|
addUseEnvironmentOptions(yargs);
|
|
@@ -75,7 +75,7 @@ exports.handler = async (options) => {
|
|
|
75
75
|
default: latestBuild.buildId === deployedBuildId
|
|
76
76
|
? undefined
|
|
77
77
|
: latestBuild.buildId,
|
|
78
|
-
validate:
|
|
78
|
+
validate: buildId => validateBuildId(buildId, deployedBuildId, latestBuild.buildId, projectName, derivedAccountId),
|
|
79
79
|
});
|
|
80
80
|
buildIdToDeploy = deployBuildIdPromptResponse.buildId;
|
|
81
81
|
}
|
package/commands/project/dev.js
CHANGED
|
@@ -14,7 +14,8 @@ const SpinniesManager = require('../../lib/ui/SpinniesManager');
|
|
|
14
14
|
const LocalDevManager = require('../../lib/LocalDevManager');
|
|
15
15
|
const { isSandbox, isDeveloperTestAccount, isStandardAccount, isAppDeveloperAccount, } = require('../../lib/accountTypes');
|
|
16
16
|
const { getValidEnv } = require('@hubspot/local-dev-lib/environment');
|
|
17
|
-
const {
|
|
17
|
+
const { ComponentTypes } = require('../../types/Projects');
|
|
18
|
+
const { findProjectComponents, getProjectComponentTypes, } = require('../../lib/projects/structure');
|
|
18
19
|
const { confirmDefaultAccountIsTarget, suggestRecommendedNestedAccount, checkIfDefaultAccountIsSupported, createSandboxForLocalDev, createDeveloperTestAccountForLocalDev, createNewProjectForLocalDev, createInitialBuildForNewProject, useExistingDevTestAccount, checkIfAccountFlagIsSupported, checkIfParentAccountIsAuthed, } = require('../../lib/localDev');
|
|
19
20
|
const i18nKey = 'commands.project.subcommands.dev';
|
|
20
21
|
exports.command = 'dev';
|
|
@@ -35,8 +36,8 @@ exports.handler = async (options) => {
|
|
|
35
36
|
const components = await findProjectComponents(projectDir);
|
|
36
37
|
const runnableComponents = components.filter(component => component.runnable);
|
|
37
38
|
const componentTypes = getProjectComponentTypes(runnableComponents);
|
|
38
|
-
const hasPrivateApps = !!componentTypes[
|
|
39
|
-
const hasPublicApps = !!componentTypes[
|
|
39
|
+
const hasPrivateApps = !!componentTypes[ComponentTypes.PrivateApp];
|
|
40
|
+
const hasPublicApps = !!componentTypes[ComponentTypes.PublicApp];
|
|
40
41
|
if (runnableComponents.length === 0) {
|
|
41
42
|
logger.error(i18n(`${i18nKey}.errors.noRunnableComponents`, {
|
|
42
43
|
projectDir,
|
|
@@ -9,16 +9,14 @@ const { promptUser } = require('../../lib/prompts/promptUtils');
|
|
|
9
9
|
const path = require('path');
|
|
10
10
|
const { i18n } = require('../../lib/lang');
|
|
11
11
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
12
|
-
const { getAccountId } = require('../../lib/commonOpts');
|
|
13
12
|
const { uiBetaTag } = require('../../lib/ui');
|
|
14
13
|
const i18nKey = `commands.project.subcommands.installDeps`;
|
|
15
14
|
exports.command = 'install-deps [packages..]';
|
|
16
15
|
exports.describe = uiBetaTag(i18n(`${i18nKey}.help.describe`), false);
|
|
17
16
|
exports.handler = async (options) => {
|
|
18
|
-
const { packages } = options || {};
|
|
17
|
+
const { derivedAccountId, packages } = options || {};
|
|
19
18
|
try {
|
|
20
|
-
|
|
21
|
-
trackCommandUsage('project-install-deps', null, accountId);
|
|
19
|
+
trackCommandUsage('project-install-deps', null, derivedAccountId);
|
|
22
20
|
const projectConfig = await getProjectConfig();
|
|
23
21
|
if (!projectConfig || !projectConfig.projectDir) {
|
|
24
22
|
logger.error(i18n(`${i18nKey}.noProjectConfig`));
|
|
@@ -126,7 +126,7 @@ exports.handler = async (options) => {
|
|
|
126
126
|
});
|
|
127
127
|
const { data: migrateResponse } = await migrateApp(derivedAccountId, appId, projectName);
|
|
128
128
|
const { id } = migrateResponse;
|
|
129
|
-
const pollResponse = await poll(checkMigrationStatus
|
|
129
|
+
const pollResponse = await poll(() => checkMigrationStatus(derivedAccountId, id));
|
|
130
130
|
const { status, project } = pollResponse;
|
|
131
131
|
if (status === 'SUCCESS') {
|
|
132
132
|
const absoluteDestPath = path.resolve(getCwd(), projectDest);
|
|
@@ -22,17 +22,17 @@ exports.handler = async (options) => {
|
|
|
22
22
|
const { forceCreate, message, derivedAccountId } = options;
|
|
23
23
|
const accountConfig = getAccountConfig(derivedAccountId);
|
|
24
24
|
const accountType = accountConfig && accountConfig.accountType;
|
|
25
|
-
const { projectConfig, projectDir } = await getProjectConfig();
|
|
26
25
|
trackCommandUsage('project-upload', { type: accountType }, derivedAccountId);
|
|
26
|
+
const { projectConfig, projectDir } = await getProjectConfig();
|
|
27
27
|
validateProjectConfig(projectConfig, projectDir);
|
|
28
28
|
await ensureProjectExists(derivedAccountId, projectConfig.name, {
|
|
29
29
|
forceCreate,
|
|
30
30
|
uploadCommand: true,
|
|
31
31
|
});
|
|
32
32
|
try {
|
|
33
|
-
const result = await handleProjectUpload(derivedAccountId, projectConfig, projectDir, pollProjectBuildAndDeploy, message
|
|
34
|
-
if (
|
|
35
|
-
if (isSpecifiedError(
|
|
33
|
+
const { result, uploadError } = await handleProjectUpload(derivedAccountId, projectConfig, projectDir, pollProjectBuildAndDeploy, message);
|
|
34
|
+
if (uploadError) {
|
|
35
|
+
if (isSpecifiedError(uploadError, {
|
|
36
36
|
subCategory: PROJECT_ERROR_TYPES.PROJECT_LOCKED,
|
|
37
37
|
})) {
|
|
38
38
|
logger.log();
|
|
@@ -40,7 +40,7 @@ exports.handler = async (options) => {
|
|
|
40
40
|
logger.log();
|
|
41
41
|
}
|
|
42
42
|
else {
|
|
43
|
-
logError(
|
|
43
|
+
logError(uploadError, new ApiErrorContext({
|
|
44
44
|
accountId: derivedAccountId,
|
|
45
45
|
request: 'project upload',
|
|
46
46
|
}));
|
|
@@ -80,11 +80,6 @@ exports.builder = yargs => {
|
|
|
80
80
|
type: 'string',
|
|
81
81
|
default: '',
|
|
82
82
|
},
|
|
83
|
-
translate: {
|
|
84
|
-
hidden: true,
|
|
85
|
-
type: 'boolean',
|
|
86
|
-
default: false,
|
|
87
|
-
},
|
|
88
83
|
});
|
|
89
84
|
yargs.example([['$0 project upload', i18n(`${i18nKey}.examples.default`)]]);
|
|
90
85
|
addConfigOptions(yargs);
|
|
@@ -71,9 +71,9 @@ exports.handler = async (options) => {
|
|
|
71
71
|
};
|
|
72
72
|
// Upload all files if no build exists for this project yet
|
|
73
73
|
if (initialUpload || hasNoBuilds) {
|
|
74
|
-
const
|
|
75
|
-
if (
|
|
76
|
-
if (isSpecifiedError(
|
|
74
|
+
const { uploadError } = await handleProjectUpload(derivedAccountId, projectConfig, projectDir, startWatching);
|
|
75
|
+
if (uploadError) {
|
|
76
|
+
if (isSpecifiedError(uploadError, {
|
|
77
77
|
subCategory: PROJECT_ERROR_TYPES.PROJECT_LOCKED,
|
|
78
78
|
})) {
|
|
79
79
|
logger.log();
|
|
@@ -81,7 +81,7 @@ exports.handler = async (options) => {
|
|
|
81
81
|
logger.log();
|
|
82
82
|
}
|
|
83
83
|
else {
|
|
84
|
-
logError(
|
|
84
|
+
logError(uploadError, new ApiErrorContext({
|
|
85
85
|
accountId: derivedAccountId,
|
|
86
86
|
request: 'project upload',
|
|
87
87
|
}));
|
|
@@ -6,7 +6,7 @@ const { i18n } = require('../../lib/lang');
|
|
|
6
6
|
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
7
7
|
const { getAccountConfig, getEnv } = require('@hubspot/local-dev-lib/config');
|
|
8
8
|
const { uiFeatureHighlight, uiBetaTag } = require('../../lib/ui');
|
|
9
|
-
const {
|
|
9
|
+
const { SANDBOX_TYPE_MAP, getAvailableSyncTypes, SYNC_TYPES, validateSandboxUsageLimits, } = require('../../lib/sandboxes');
|
|
10
10
|
const { getValidEnv } = require('@hubspot/local-dev-lib/environment');
|
|
11
11
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
12
12
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
@@ -17,7 +17,7 @@ const { logError } = require('../../lib/errorHandlers/index');
|
|
|
17
17
|
const { isMissingScopeError } = require('@hubspot/local-dev-lib/errors/index');
|
|
18
18
|
const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
|
|
19
19
|
const { HUBSPOT_ACCOUNT_TYPES, HUBSPOT_ACCOUNT_TYPE_STRINGS, } = require('@hubspot/local-dev-lib/constants/config');
|
|
20
|
-
const {
|
|
20
|
+
const { buildSandbox } = require('../../lib/buildAccount');
|
|
21
21
|
const { hubspotAccountNamePrompt, } = require('../../lib/prompts/accountNamePrompt');
|
|
22
22
|
const i18nKey = 'commands.sandbox.subcommands.create';
|
|
23
23
|
exports.command = 'create';
|
|
@@ -38,7 +38,7 @@ exports.handler = async (options) => {
|
|
|
38
38
|
}
|
|
39
39
|
let typePrompt;
|
|
40
40
|
let namePrompt;
|
|
41
|
-
if ((type && !
|
|
41
|
+
if ((type && !SANDBOX_TYPE_MAP[type.toLowerCase()]) || !type) {
|
|
42
42
|
if (!force) {
|
|
43
43
|
typePrompt = await sandboxTypePrompt();
|
|
44
44
|
}
|
|
@@ -48,7 +48,7 @@ exports.handler = async (options) => {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
const sandboxType = type
|
|
51
|
-
?
|
|
51
|
+
? SANDBOX_TYPE_MAP[type.toLowerCase()]
|
|
52
52
|
: typePrompt.type;
|
|
53
53
|
// Check usage limits and exit if parent portal has no available sandboxes for the selected type
|
|
54
54
|
try {
|
|
@@ -97,27 +97,16 @@ exports.handler = async (options) => {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
try {
|
|
100
|
-
const
|
|
101
|
-
name: sandboxName,
|
|
102
|
-
accountType: sandboxType,
|
|
103
|
-
accountConfig,
|
|
104
|
-
env,
|
|
105
|
-
force,
|
|
106
|
-
});
|
|
100
|
+
const result = await buildSandbox(sandboxName, accountConfig, sandboxType, env, force);
|
|
107
101
|
const sandboxAccountConfig = getAccountConfig(result.sandbox.sandboxHubId);
|
|
108
102
|
// For v1 sandboxes, keep sync here. Once we migrate to v2, this will be handled by BE automatically
|
|
109
103
|
const handleSyncSandbox = async (syncTasks) => {
|
|
110
|
-
await syncSandbox(
|
|
111
|
-
accountConfig: sandboxAccountConfig,
|
|
112
|
-
parentAccountConfig: accountConfig,
|
|
113
|
-
env,
|
|
114
|
-
syncTasks,
|
|
115
|
-
});
|
|
104
|
+
await syncSandbox(sandboxAccountConfig, accountConfig, env, syncTasks);
|
|
116
105
|
};
|
|
117
106
|
try {
|
|
118
107
|
let availableSyncTasks = await getAvailableSyncTypes(accountConfig, sandboxAccountConfig);
|
|
119
108
|
if (!contactRecordsSyncPromptResult) {
|
|
120
|
-
availableSyncTasks = availableSyncTasks.filter(t => t.type !==
|
|
109
|
+
availableSyncTasks = availableSyncTasks.filter(t => t.type !== SYNC_TYPES.OBJECT_RECORDS);
|
|
121
110
|
}
|
|
122
111
|
await handleSyncSandbox(availableSyncTasks);
|
|
123
112
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
// @ts-nocheck
|
|
4
|
-
const { addAccountOptions, addConfigOptions, addUseEnvironmentOptions,
|
|
4
|
+
const { addAccountOptions, addConfigOptions, addUseEnvironmentOptions, addTestingOptions, } = require('../../lib/commonOpts');
|
|
5
5
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
6
6
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
7
7
|
const { logError, debugError } = require('../../lib/errorHandlers/index');
|
|
@@ -9,7 +9,7 @@ const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/index');
|
|
|
9
9
|
const { deleteSandbox } = require('@hubspot/local-dev-lib/api/sandboxHubs');
|
|
10
10
|
const { i18n } = require('../../lib/lang');
|
|
11
11
|
const { deleteSandboxPrompt } = require('../../lib/prompts/sandboxesPrompt');
|
|
12
|
-
const { getEnv, removeSandboxAccountFromConfig, updateDefaultAccount,
|
|
12
|
+
const { getEnv, removeSandboxAccountFromConfig, updateDefaultAccount, getAccountId, getConfigAccounts, } = require('@hubspot/local-dev-lib/config');
|
|
13
13
|
const { getAccountIdentifier, } = require('@hubspot/local-dev-lib/config/getAccountIdentifier');
|
|
14
14
|
const { selectAccountFromConfig } = require('../../lib/prompts/accountsPrompt');
|
|
15
15
|
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
@@ -40,10 +40,8 @@ exports.handler = async (options) => {
|
|
|
40
40
|
process.exit(EXIT_CODES.ERROR);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
const sandboxAccountId = getAccountId(
|
|
44
|
-
|
|
45
|
-
});
|
|
46
|
-
const isDefaultAccount = sandboxAccountId === getAccountId(getConfigDefaultAccount());
|
|
43
|
+
const sandboxAccountId = getAccountId(providedAccountId || accountPrompt.account);
|
|
44
|
+
const isDefaultAccount = sandboxAccountId === getAccountId();
|
|
47
45
|
const baseUrl = getHubSpotWebsiteOrigin(getValidEnv(getEnv(sandboxAccountId)));
|
|
48
46
|
let parentAccountId;
|
|
49
47
|
const accountsList = getConfigAccounts();
|
|
@@ -54,9 +52,7 @@ exports.handler = async (options) => {
|
|
|
54
52
|
}
|
|
55
53
|
else if (!force) {
|
|
56
54
|
const parentAccountPrompt = await deleteSandboxPrompt(true);
|
|
57
|
-
parentAccountId = getAccountId(
|
|
58
|
-
account: parentAccountPrompt.account,
|
|
59
|
-
});
|
|
55
|
+
parentAccountId = getAccountId(parentAccountPrompt.account);
|
|
60
56
|
}
|
|
61
57
|
else {
|
|
62
58
|
logger.error(i18n(`${i18nKey}.failure.noParentAccount`));
|
|
@@ -66,7 +62,7 @@ exports.handler = async (options) => {
|
|
|
66
62
|
}
|
|
67
63
|
const url = `${baseUrl}/sandboxes/${parentAccountId}`;
|
|
68
64
|
const command = `hs auth ${getEnv(sandboxAccountId) === 'qa' ? '--qa' : ''} --account=${parentAccountId}`;
|
|
69
|
-
if (parentAccountId && !getAccountId(
|
|
65
|
+
if (parentAccountId && !getAccountId(parentAccountId)) {
|
|
70
66
|
logger.log('');
|
|
71
67
|
logger.error(i18n(`${i18nKey}.failure.noParentPortalAvailable`, {
|
|
72
68
|
parentAccountId,
|
|
@@ -17,7 +17,8 @@ const { ApiErrorContext, logError } = require('../../lib/errorHandlers/index');
|
|
|
17
17
|
const { handleExit, handleKeypress } = require('../../lib/process');
|
|
18
18
|
const { getThemeJSONPath } = require('@hubspot/local-dev-lib/cms/themes');
|
|
19
19
|
const { getProjectConfig } = require('../../lib/projects');
|
|
20
|
-
const { findProjectComponents
|
|
20
|
+
const { findProjectComponents } = require('../../lib/projects/structure');
|
|
21
|
+
const { ComponentTypes } = require('../../types/Projects');
|
|
21
22
|
const { preview } = require('@hubspot/theme-preview-dev-server');
|
|
22
23
|
const { hasFeature } = require('../../lib/hasFeature');
|
|
23
24
|
const i18nKey = 'commands.theme.subcommands.preview';
|
|
@@ -73,7 +74,7 @@ const determineSrcAndDest = async (options) => {
|
|
|
73
74
|
let themeJsonPath = getThemeJSONPath();
|
|
74
75
|
if (!themeJsonPath) {
|
|
75
76
|
const projectComponents = await findProjectComponents(projectDir);
|
|
76
|
-
const themeComponents = projectComponents.filter(c => c.type ===
|
|
77
|
+
const themeComponents = projectComponents.filter(c => c.type === ComponentTypes.HublTheme);
|
|
77
78
|
if (themeComponents.length === 0) {
|
|
78
79
|
logger.error(i18n(`${i18nKey}.errors.noThemeComponents`));
|
|
79
80
|
process.exit(EXIT_CODES.ERROR);
|