@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.
Files changed (73) hide show
  1. package/README.md +3 -2
  2. package/bin/cli.js +37 -5
  3. package/commands/account/info.d.ts +7 -0
  4. package/commands/account/info.js +28 -25
  5. package/commands/account/remove.js +4 -4
  6. package/commands/account/use.js +3 -3
  7. package/commands/auth.js +3 -3
  8. package/commands/customObject/create.js +4 -1
  9. package/commands/function/deploy.js +1 -1
  10. package/commands/hubdb/create.js +2 -2
  11. package/commands/init.js +1 -1
  12. package/commands/logs.js +1 -7
  13. package/commands/project/cloneApp.js +1 -1
  14. package/commands/project/create.js +6 -0
  15. package/commands/project/deploy.js +1 -1
  16. package/commands/project/dev.js +4 -3
  17. package/commands/project/installDeps.js +2 -4
  18. package/commands/project/migrateApp.js +1 -1
  19. package/commands/project/upload.js +5 -10
  20. package/commands/project/watch.js +4 -4
  21. package/commands/sandbox/create.js +7 -18
  22. package/commands/sandbox/delete.js +6 -10
  23. package/commands/theme/preview.js +3 -2
  24. package/lang/en.lyaml +15 -6
  25. package/lib/DevServerManager.d.ts +40 -1
  26. package/lib/DevServerManager.js +39 -30
  27. package/lib/LocalDevManager.d.ts +58 -1
  28. package/lib/LocalDevManager.js +162 -121
  29. package/lib/buildAccount.d.ts +12 -0
  30. package/lib/buildAccount.js +110 -95
  31. package/lib/commonOpts.d.ts +4 -15
  32. package/lib/commonOpts.js +2 -28
  33. package/lib/constants.d.ts +1 -7
  34. package/lib/constants.js +2 -8
  35. package/lib/dependencyManagement.d.ts +9 -4
  36. package/lib/dependencyManagement.js +45 -49
  37. package/lib/developerTestAccounts.d.ts +1 -0
  38. package/lib/developerTestAccounts.js +1 -0
  39. package/lib/errorHandlers/index.js +5 -2
  40. package/lib/localDev.d.ts +17 -1
  41. package/lib/localDev.js +203 -203
  42. package/lib/polling.d.ts +13 -5
  43. package/lib/polling.js +21 -7
  44. package/lib/projects/buildAndDeploy.d.ts +1 -7
  45. package/lib/projects/buildAndDeploy.js +3 -3
  46. package/lib/projects/index.js +9 -4
  47. package/lib/projects/structure.d.ts +5 -71
  48. package/lib/projects/structure.js +27 -10
  49. package/lib/projects/upload.d.ts +4 -3
  50. package/lib/projects/upload.js +7 -30
  51. package/lib/projects/watch.d.ts +3 -0
  52. package/lib/projects/watch.js +73 -70
  53. package/lib/prompts/createProjectPrompt.js +8 -1
  54. package/lib/prompts/installPublicAppPrompt.d.ts +1 -1
  55. package/lib/prompts/personalAccessKeyPrompt.d.ts +1 -1
  56. package/lib/prompts/projectDevTargetAccountPrompt.d.ts +2 -2
  57. package/lib/sandboxSync.d.ts +4 -1
  58. package/lib/sandboxSync.js +67 -68
  59. package/lib/sandboxes.d.ts +20 -1
  60. package/lib/sandboxes.js +77 -175
  61. package/lib/serverlessLogs.d.ts +4 -1
  62. package/lib/serverlessLogs.js +64 -60
  63. package/lib/ui/serverlessFunctionLogs.d.ts +8 -0
  64. package/lib/ui/serverlessFunctionLogs.js +1 -3
  65. package/lib/validation.d.ts +2 -0
  66. package/lib/validation.js +5 -8
  67. package/package.json +9 -9
  68. package/types/Projects.d.ts +74 -0
  69. package/types/Projects.js +7 -0
  70. package/types/Sandboxes.d.ts +3 -0
  71. package/types/Sandboxes.js +2 -0
  72. package/types/Yargs.d.ts +14 -0
  73. package/types/Yargs.js +2 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @hubspot/cli
2
2
 
3
- [![Official Release](https://img.shields.io/npm/v/@hubspot/cli/latest?label=Official%20Release)](https://www.npmjs.com/package/@hubspot/cli) [![Latest Version](https://img.shields.io/github/v/tag/hubspot/hubspot-cli?label=Latest%20Version)](https://www.npmjs.com/package/@hubspot/cli?activeTab=versions)
3
+ [![Official Release](https://img.shields.io/npm/v/@hubspot/cli/latest?label=Official%20Release)](https://www.npmjs.com/package/@hubspot/cli) [![Latest Beta Version](https://img.shields.io/npm/v/@hubspot/cli/next?label=Latest%20Beta%20Version)](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, injectAccountIdMiddleware, } = require('../lib/commonOpts');
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._.includes('init')) {
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 {};
@@ -1,38 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- // @ts-nocheck
4
- const { logger } = require('@hubspot/local-dev-lib/logger');
5
- const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
6
- const { getAccessToken } = require('@hubspot/local-dev-lib/personalAccessKey');
7
- const { addConfigOptions } = require('../../lib/commonOpts');
8
- const { i18n } = require('../../lib/lang');
9
- const { getTableContents } = require('../../lib/ui/table');
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
- exports.handler = async (options) => {
14
- const { derivedAccountId } = options;
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
- const response = await getAccessToken(personalAccessKey, env, derivedAccountId);
20
- const scopeGroups = response.scopeGroups.map(s => [s]);
21
- logger.log(i18n(`${i18nKey}.name`, { name }));
22
- logger.log(i18n(`${i18nKey}.accountId`, { accountId: derivedAccountId }));
23
- logger.log(i18n(`${i18nKey}.scopeGroups`));
24
- logger.log(getTableContents(scopeGroups, { border: { bodyLeft: ' ' } }));
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
- exports.builder = yargs => {
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: getAccountIdFromConfig, updateDefaultAccount, } = require('@hubspot/local-dev-lib/config');
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 && !getAccountIdFromConfig(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 || !getAccountIdFromConfig(accountToRemove)) {
22
+ if (!accountToRemove || !getAccountId(accountToRemove)) {
23
23
  accountToRemove = await selectAccountFromConfig(i18n(`${i18nKey}.prompts.selectAccountToRemove`));
24
24
  }
25
- trackCommandUsage('accounts-remove', null, getAccountIdFromConfig(accountToRemove));
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`, {
@@ -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: getAccountIdFromConfig, } = require('@hubspot/local-dev-lib/config');
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 (!getAccountIdFromConfig(newDefaultAccount)) {
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, getAccountIdFromConfig(newDefaultAccount));
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, getAccountId, addTestingOptions, addGlobalOptions, } = require('../lib/commonOpts');
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({ account: accountName });
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, derivedAccountId, buildId);
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);
@@ -42,9 +42,9 @@ exports.handler = async (options) => {
42
42
  trackCommandUsage('hubdb-create', null, derivedAccountId);
43
43
  let filePath;
44
44
  try {
45
- const { path: filePath } = 'path' in options
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 { auth: authTypeFlagValue, c: configFlagValue, providedAccountId, disableTracking, useHiddenConfig, } = options;
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, derivedAccountId, exportId);
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: () => validateBuildId(buildId, deployedBuildId, latestBuild.buildId, projectName, derivedAccountId),
78
+ validate: buildId => validateBuildId(buildId, deployedBuildId, latestBuild.buildId, projectName, derivedAccountId),
79
79
  });
80
80
  buildIdToDeploy = deployBuildIdPromptResponse.buildId;
81
81
  }
@@ -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 { findProjectComponents, getProjectComponentTypes, COMPONENT_TYPES, } = require('../../lib/projects/structure');
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[COMPONENT_TYPES.privateApp];
39
- const hasPublicApps = !!componentTypes[COMPONENT_TYPES.publicApp];
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
- const accountId = getAccountId(options);
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, derivedAccountId, id);
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, options.translate);
34
- if (result.uploadError) {
35
- if (isSpecifiedError(result.uploadError, {
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(result.uploadError, new ApiErrorContext({
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 result = await handleProjectUpload(derivedAccountId, projectConfig, projectDir, startWatching);
75
- if (result.uploadError) {
76
- if (isSpecifiedError(result.uploadError, {
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(result.uploadError, new ApiErrorContext({
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 { sandboxTypeMap, getAvailableSyncTypes, syncTypes, validateSandboxUsageLimits, } = require('../../lib/sandboxes');
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 { buildNewAccount } = require('../../lib/buildAccount');
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 && !sandboxTypeMap[type.toLowerCase()]) || !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
- ? sandboxTypeMap[type.toLowerCase()]
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 { result } = await buildNewAccount({
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 !== syncTypes.OBJECT_RECORDS);
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, getAccountId, addTestingOptions, } = require('../../lib/commonOpts');
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, getConfigDefaultAccount, getConfigAccounts, } = require('@hubspot/local-dev-lib/config');
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
- account: providedAccountId || accountPrompt.account,
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({ account: parentAccountId })) {
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, COMPONENT_TYPES, } = require('../../lib/projects/structure');
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 === COMPONENT_TYPES.hublTheme);
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);