@hubspot/cli 4.0.1-beta.0 → 4.0.1-beta.3

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 CHANGED
@@ -133,7 +133,7 @@ hs hubdb delete <id or name>
133
133
 
134
134
  ## Authentication
135
135
 
136
- There are three ways that the tools can authenticate with HubSpot.
136
+ There are two ways that the tools can authenticate with HubSpot.
137
137
 
138
138
  ### Personal Access Key (recommended)
139
139
 
@@ -146,20 +146,6 @@ There are three ways that the tools can authenticate with HubSpot.
146
146
  3. Select `OAuth2` and follow the steps
147
147
 
148
148
  _**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._
149
-
150
- ### HubSpot API Key
151
-
152
- 1. [Set up an API Key for the Account](https://knowledge.hubspot.com/articles/kcs_article/integrations/how-do-i-get-my-hubspot-api-key)
153
- 2. Edit the [hubspot.config.yml](../../docs/HubspotConfigFile.md) file to set the `authType` for the account to `apikey` and add `apiKey` as shown below:
154
-
155
- ```yaml
156
- defaultPortal: DEV
157
- portals:
158
- - name: DEV
159
- portalId: 123
160
- authType: apikey
161
- apiKey: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
162
- ```
163
149
  ### Exit Codes
164
150
 
165
151
  The CLI will exit with one of the following exit codes:
@@ -0,0 +1,53 @@
1
+ const { logger } = require('@hubspot/cli-lib/logger');
2
+ const { getAccountConfig } = require('@hubspot/cli-lib/lib/config');
3
+ const { getAccessToken } = require('@hubspot/cli-lib/personalAccessKey.js');
4
+ const {
5
+ getAccountId,
6
+ addAccountOptions,
7
+ addConfigOptions,
8
+ } = require('../../lib/commonOpts');
9
+ const { loadAndValidateOptions } = require('../../lib/validation');
10
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
11
+
12
+ const i18nKey = 'cli.commands.accounts.subcommands.info';
13
+ exports.describe = i18n(`${i18nKey}.describe`);
14
+
15
+ exports.command = 'info [--account]';
16
+
17
+ exports.handler = async options => {
18
+ await loadAndValidateOptions(options);
19
+
20
+ let accountId = getAccountId(options);
21
+ const config = getAccountConfig(accountId);
22
+
23
+ // check if the provided account is using a personal access key, if not, show an error
24
+ if (config.authType === 'personalaccesskey') {
25
+ const { name, personalAccessKey, env } = config;
26
+
27
+ const response = await getAccessToken(personalAccessKey, env, accountId);
28
+
29
+ let scopeGroups = response.scopeGroups.join('\n');
30
+
31
+ logger.log(i18n(`${i18nKey}.name`, { name }));
32
+ logger.log(i18n(`${i18nKey}.accountId`, { accountId }));
33
+ logger.log(i18n(`${i18nKey}.scopeGroups`, { scopeGroups }));
34
+ } else {
35
+ logger.log(i18n(`${i18nKey}.errors.notUsingPersonalAccessKey`));
36
+ }
37
+ };
38
+
39
+ exports.builder = yargs => {
40
+ addConfigOptions(yargs, true);
41
+ addAccountOptions(yargs, true);
42
+
43
+ yargs.example([
44
+ ['$0 accounts info', i18n(`${i18nKey}.examples.default`)],
45
+ [
46
+ '$0 accounts info --account=MyAccount',
47
+ i18n(`${i18nKey}.examples.nameBased`),
48
+ ],
49
+ ['$0 accounts info --account=1234567', i18n(`${i18nKey}.examples.idBased`)],
50
+ ]);
51
+
52
+ return yargs;
53
+ };
@@ -19,6 +19,54 @@ const i18nKey = 'cli.commands.accounts.subcommands.list';
19
19
  exports.command = 'list';
20
20
  exports.describe = i18n(`${i18nKey}.describe`);
21
21
 
22
+ const sortAndMapPortals = portals => {
23
+ const mappedPortalData = {};
24
+ portals
25
+ .sort((a, b) => {
26
+ if (a.sandboxAccountType === null && b.sandboxAccountType !== null) {
27
+ return -1;
28
+ }
29
+ if (a.sandboxAccountType !== null && b.sandboxAccountType === null) {
30
+ return 1;
31
+ }
32
+ return 0;
33
+ })
34
+ .forEach(portal => {
35
+ if (
36
+ portal.sandboxAccountType !== undefined &&
37
+ portal.sandboxAccountType === null
38
+ ) {
39
+ mappedPortalData[portal.portalId] = [portal];
40
+ } else if (portal.sandboxAccountType && portal.parentAccountId) {
41
+ mappedPortalData[portal.parentAccountId] = [
42
+ ...(mappedPortalData[portal.parentAccountId] || []),
43
+ portal,
44
+ ];
45
+ } else {
46
+ mappedPortalData[portal.portalId] = [portal];
47
+ }
48
+ });
49
+ return mappedPortalData;
50
+ };
51
+
52
+ const getPortalData = mappedPortalData => {
53
+ const portalData = [];
54
+ Object.values(mappedPortalData).forEach(set => {
55
+ set.forEach((portal, i) => {
56
+ if (i === 0) {
57
+ portalData.push([portal.name, portal.portalId, portal.authType]);
58
+ } else {
59
+ portalData.push([
60
+ `↳ ${portal.name} [sandbox]`,
61
+ portal.portalId,
62
+ portal.authType,
63
+ ]);
64
+ }
65
+ });
66
+ });
67
+ return portalData;
68
+ };
69
+
22
70
  exports.handler = async options => {
23
71
  await loadAndValidateOptions(options);
24
72
 
@@ -28,9 +76,8 @@ exports.handler = async options => {
28
76
 
29
77
  const config = getConfig();
30
78
  const configPath = getConfigPath();
31
- const portalData = config.portals.map(portal => {
32
- return [portal.name, portal.portalId, portal.authType];
33
- });
79
+ const mappedPortalData = sortAndMapPortals(config.portals);
80
+ const portalData = getPortalData(mappedPortalData);
34
81
  portalData.unshift(
35
82
  getTableHeader([
36
83
  i18n(`${i18nKey}.labels.name`),
@@ -3,6 +3,7 @@ const { i18n } = require('@hubspot/cli-lib/lib/lang');
3
3
  const list = require('./accounts/list');
4
4
  const rename = require('./accounts/rename');
5
5
  const use = require('./accounts/use');
6
+ const info = require('./accounts/info');
6
7
 
7
8
  const i18nKey = 'cli.commands.accounts';
8
9
 
@@ -20,6 +21,7 @@ exports.builder = yargs => {
20
21
  })
21
22
  .command(rename)
22
23
  .command(use)
24
+ .command(info)
23
25
  .demandCommand(1, '');
24
26
 
25
27
  return yargs;
package/commands/auth.js CHANGED
@@ -3,7 +3,6 @@ const { logger } = require('@hubspot/cli-lib/logger');
3
3
  const {
4
4
  OAUTH_AUTH_METHOD,
5
5
  PERSONAL_ACCESS_KEY_AUTH_METHOD,
6
- API_KEY_AUTH_METHOD,
7
6
  ENVIRONMENTS,
8
7
  DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
9
8
  } = require('@hubspot/cli-lib/lib/constants');
@@ -22,7 +21,6 @@ const { promptUser } = require('../lib/prompts/promptUtils');
22
21
  const {
23
22
  personalAccessKeyPrompt,
24
23
  OAUTH_FLOW,
25
- API_KEY_FLOW,
26
24
  } = require('../lib/prompts/personalAccessKeyPrompt');
27
25
  const {
28
26
  enterAccountNamePrompt,
@@ -80,25 +78,6 @@ exports.handler = async options => {
80
78
  let successAuthMethod;
81
79
 
82
80
  switch (authType) {
83
- case API_KEY_AUTH_METHOD.value:
84
- configData = await promptUser(API_KEY_FLOW);
85
- updatedConfig = await updateAccountConfig(configData);
86
- validName = updatedConfig.name;
87
-
88
- if (!validName) {
89
- const { name: namePrompt } = await enterAccountNamePrompt();
90
- validName = namePrompt;
91
- }
92
-
93
- updateAccountConfig({
94
- ...updatedConfig,
95
- environment: updatedConfig.env,
96
- name: validName,
97
- });
98
- writeConfig();
99
-
100
- successAuthMethod = API_KEY_AUTH_METHOD.name;
101
- break;
102
81
  case OAUTH_AUTH_METHOD.value:
103
82
  configData = await promptUser(OAUTH_FLOW);
104
83
  await authenticateWithOauth({
@@ -188,7 +167,6 @@ exports.builder = yargs => {
188
167
  choices: [
189
168
  `${PERSONAL_ACCESS_KEY_AUTH_METHOD.value}`,
190
169
  `${OAUTH_AUTH_METHOD.value}`,
191
- `${API_KEY_AUTH_METHOD.value}`,
192
170
  ],
193
171
  default: PERSONAL_ACCESS_KEY_AUTH_METHOD.value,
194
172
  defaultDescription: i18n(`${i18nKey}.positionals.type.defaultDescription`, {
@@ -35,7 +35,7 @@ exports.handler = async options => {
35
35
  trackCommandUsage('filemanager-fetch', {}, accountId);
36
36
 
37
37
  // Fetch and write file/folder.
38
- downloadFileOrFolder(accountId, src, dest, options);
38
+ await downloadFileOrFolder(accountId, src, dest, options);
39
39
  };
40
40
 
41
41
  exports.builder = yargs => {
package/commands/init.js CHANGED
@@ -5,8 +5,6 @@ const {
5
5
  createEmptyConfigFile,
6
6
  deleteEmptyConfigFile,
7
7
  updateDefaultAccount,
8
- writeConfig,
9
- updateAccountConfig,
10
8
  } = require('@hubspot/cli-lib/lib/config');
11
9
  const { addConfigOptions } = require('../lib/commonOpts');
12
10
  const { handleExit } = require('@hubspot/cli-lib/lib/process');
@@ -15,7 +13,6 @@ const {
15
13
  DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
16
14
  PERSONAL_ACCESS_KEY_AUTH_METHOD,
17
15
  OAUTH_AUTH_METHOD,
18
- API_KEY_AUTH_METHOD,
19
16
  ENVIRONMENTS,
20
17
  } = require('@hubspot/cli-lib/lib/constants');
21
18
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
@@ -29,7 +26,6 @@ const { setLogLevel, addTestingOptions } = require('../lib/commonOpts');
29
26
  const { promptUser } = require('../lib/prompts/promptUtils');
30
27
  const {
31
28
  OAUTH_FLOW,
32
- API_KEY_FLOW,
33
29
  personalAccessKeyPrompt,
34
30
  } = require('../lib/prompts/personalAccessKeyPrompt');
35
31
  const {
@@ -70,28 +66,14 @@ const oauthConfigCreationFlow = async env => {
70
66
  return accountConfig;
71
67
  };
72
68
 
73
- const apiKeyConfigCreationFlow = async env => {
74
- const configData = await promptUser(API_KEY_FLOW);
75
- const accountConfig = {
76
- ...configData,
77
- env,
78
- };
79
- updateAccountConfig(accountConfig);
80
- updateDefaultAccount(accountConfig.name);
81
- writeConfig();
82
- return accountConfig;
83
- };
84
-
85
69
  const CONFIG_CREATION_FLOWS = {
86
70
  [PERSONAL_ACCESS_KEY_AUTH_METHOD.value]: personalAccessKeyConfigCreationFlow,
87
71
  [OAUTH_AUTH_METHOD.value]: oauthConfigCreationFlow,
88
- [API_KEY_AUTH_METHOD.value]: apiKeyConfigCreationFlow,
89
72
  };
90
73
 
91
74
  const AUTH_TYPE_NAMES = {
92
75
  [PERSONAL_ACCESS_KEY_AUTH_METHOD.value]: PERSONAL_ACCESS_KEY_AUTH_METHOD.name,
93
76
  [OAUTH_AUTH_METHOD.value]: OAUTH_AUTH_METHOD.name,
94
- [API_KEY_AUTH_METHOD.value]: API_KEY_AUTH_METHOD.name,
95
77
  };
96
78
 
97
79
  exports.command = 'init [--account]';
@@ -164,7 +146,6 @@ exports.builder = yargs => {
164
146
  choices: [
165
147
  `${PERSONAL_ACCESS_KEY_AUTH_METHOD.value}`,
166
148
  `${OAUTH_AUTH_METHOD.value}`,
167
- `${API_KEY_AUTH_METHOD.value}`,
168
149
  ],
169
150
  default: PERSONAL_ACCESS_KEY_AUTH_METHOD.value,
170
151
  defaultDescription: i18n(`${i18nKey}.options.auth.defaultDescription`, {
@@ -10,7 +10,10 @@ const {
10
10
  const { trackCommandUsage } = require('../../lib/usageTracking');
11
11
  const { logger } = require('@hubspot/cli-lib/logger');
12
12
  const { outputLogs } = require('@hubspot/cli-lib/lib/logs');
13
- const { fetchProject } = require('@hubspot/cli-lib/api/dfs');
13
+ const {
14
+ fetchProject,
15
+ fetchDeployComponentsMetadata,
16
+ } = require('@hubspot/cli-lib/api/dfs');
14
17
  const {
15
18
  getTableContents,
16
19
  getTableHeader,
@@ -142,12 +145,30 @@ exports.handler = async options => {
142
145
  const endpointName = options.endpoint || promptEndpointName;
143
146
 
144
147
  let relativeAppPath;
148
+ let appId;
145
149
 
146
150
  if (appName && !endpointName) {
147
151
  await ensureProjectExists(accountId, projectName, {
148
152
  allowCreate: false,
149
153
  });
150
- const { deployedBuild } = await fetchProject(accountId, projectName);
154
+
155
+ const { deployedBuild, id: projectId } = await fetchProject(
156
+ accountId,
157
+ projectName
158
+ );
159
+
160
+ const { results: deployComponents } = await fetchDeployComponentsMetadata(
161
+ accountId,
162
+ projectId
163
+ );
164
+
165
+ const appComponent = deployComponents.find(
166
+ c => c.componentName === appName
167
+ );
168
+
169
+ if (appComponent) {
170
+ appId = appComponent.componentIdentifier;
171
+ }
151
172
 
152
173
  if (deployedBuild && deployedBuild.subbuildStatuses) {
153
174
  const appSubbuild = deployedBuild.subbuildStatuses.find(
@@ -196,10 +217,15 @@ exports.handler = async options => {
196
217
  );
197
218
 
198
219
  logger.log(
199
- uiLink(
200
- i18n(`${i18nKey}.logs.hubspotLogsLink`),
201
- getPrivateAppsUrl(accountId)
202
- )
220
+ appId
221
+ ? uiLink(
222
+ i18n(`${i18nKey}.logs.hubspotLogsDirectLink`),
223
+ `${getPrivateAppsUrl(accountId)}/${appId}/logs/extensions`
224
+ )
225
+ : uiLink(
226
+ i18n(`${i18nKey}.logs.hubspotLogsLink`),
227
+ getPrivateAppsUrl(accountId)
228
+ )
203
229
  );
204
230
  logger.log();
205
231
  uiLine();
@@ -157,6 +157,8 @@ exports.handler = async options => {
157
157
  url,
158
158
  })
159
159
  );
160
+ } else {
161
+ logger.error(err.error.message);
160
162
  }
161
163
  process.exit(EXIT_CODES.ERROR);
162
164
  }
@@ -0,0 +1,41 @@
1
+ const {
2
+ addAccountOptions,
3
+ addConfigOptions,
4
+ addUseEnvironmentOptions,
5
+ } = require('../../lib/commonOpts');
6
+ const { logger } = require('@hubspot/cli-lib/logger');
7
+
8
+ const { loadAndValidateOptions } = require('../../lib/validation');
9
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
10
+
11
+ const i18nKey = 'cli.commands.sandbox.subcommands.delete';
12
+
13
+ exports.command = 'delete';
14
+ exports.describe = i18n(`${i18nKey}.describe`);
15
+
16
+ exports.handler = async options => {
17
+ await loadAndValidateOptions(options);
18
+
19
+ logger.log('');
20
+ logger.log(i18n(`${i18nKey}.temporaryMessage`));
21
+ };
22
+
23
+ exports.builder = yargs => {
24
+ yargs.option('account', {
25
+ describe: i18n(`${i18nKey}.options.account.describe`),
26
+ type: 'string',
27
+ });
28
+
29
+ yargs.example([
30
+ [
31
+ '$0 sandbox delete --account=MySandboxAccount',
32
+ i18n(`${i18nKey}.examples.default`),
33
+ ],
34
+ ]);
35
+
36
+ addConfigOptions(yargs, true);
37
+ addAccountOptions(yargs, true);
38
+ addUseEnvironmentOptions(yargs, true);
39
+
40
+ return yargs;
41
+ };
@@ -1,5 +1,6 @@
1
1
  const { addConfigOptions, addAccountOptions } = require('../lib/commonOpts');
2
2
  const create = require('./sandbox/create');
3
+ const del = require('./sandbox/delete');
3
4
 
4
5
  // const i18nKey = 'cli.commands.sandbox';
5
6
 
@@ -10,7 +11,10 @@ exports.builder = yargs => {
10
11
  addConfigOptions(yargs, true);
11
12
  addAccountOptions(yargs, true);
12
13
 
13
- yargs.command(create).demandCommand(1, '');
14
+ yargs
15
+ .command(create)
16
+ .command(del)
17
+ .demandCommand(1, '');
14
18
 
15
19
  return yargs;
16
20
  };
@@ -11,13 +11,6 @@ allowUsageTracking: false
11
11
 
12
12
  # List of accounts that are intended to be used
13
13
  portals:
14
- # Account set up to use an API Key
15
- - name: DEV
16
- portalId: 123
17
- # Override mode for account
18
- defaultMode: draft
19
- authType: apikey
20
- apiKey: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
21
14
  # Account set up to use OAuth2
22
15
  - name: PROD
23
16
  portalId: 456
@@ -24,13 +24,6 @@ describe('validation', () => {
24
24
  getAccountConfig.mockReturnValueOnce(undefined);
25
25
  expect(await validateAccount({ account: 123 })).toBe(false);
26
26
  });
27
- it('returns false if an api key is missing', async () => {
28
- getAccountId.mockReturnValueOnce(123);
29
- getAccountConfig.mockReturnValueOnce({
30
- accountId: 123,
31
- });
32
- expect(await validateAccount({ account: 123 })).toBe(false);
33
- });
34
27
  it('returns false for oauth2 authType if auth is missing', async () => {
35
28
  getAccountId.mockReturnValueOnce(123);
36
29
  getAccountConfig.mockReturnValueOnce({
package/lib/projects.js CHANGED
@@ -449,6 +449,14 @@ const makePollTaskStatusFunc = ({
449
449
  } with the following error ---`
450
450
  );
451
451
  logger.error(subTask.errorMessage);
452
+
453
+ // Log nested errors
454
+ if (subTask.standardError && subTask.standardError.errors) {
455
+ logger.log();
456
+ subTask.standardError.errors.forEach(error => {
457
+ logger.log(error.message);
458
+ });
459
+ }
452
460
  });
453
461
  }
454
462
 
@@ -6,7 +6,6 @@ const {
6
6
  const { deleteEmptyConfigFile } = require('@hubspot/cli-lib/lib/config');
7
7
  const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
8
8
  const { logger } = require('@hubspot/cli-lib/logger');
9
- const { API_KEY_REGEX } = require('../regex');
10
9
  const { promptUser } = require('./promptUtils');
11
10
  const { accountNamePrompt } = require('./enterAccountNamePrompt');
12
11
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
@@ -89,17 +88,6 @@ const CLIENT_SECRET = {
89
88
  },
90
89
  };
91
90
 
92
- const ACCOUNT_API_KEY = {
93
- name: 'apiKey',
94
- message: i18n(`${i18nKey}.enterApiKey`),
95
- validate(val) {
96
- if (!API_KEY_REGEX.test(val)) {
97
- return i18n(`${i18nKey}.errors.invalidAPIKey`);
98
- }
99
- return true;
100
- },
101
- };
102
-
103
91
  const PERSONAL_ACCESS_KEY_BROWSER_OPEN_PREP = {
104
92
  name: 'personalAcessKeyBrowserOpenPrep',
105
93
  type: 'confirm',
@@ -142,17 +130,14 @@ const OAUTH_FLOW = [
142
130
  CLIENT_SECRET,
143
131
  SCOPES,
144
132
  ];
145
- const API_KEY_FLOW = [accountNamePrompt(), ACCOUNT_ID, ACCOUNT_API_KEY];
146
133
 
147
134
  module.exports = {
148
135
  personalAccessKeyPrompt,
149
136
  CLIENT_ID,
150
137
  CLIENT_SECRET,
151
- ACCOUNT_API_KEY,
152
138
  ACCOUNT_ID,
153
139
  SCOPES,
154
140
  PERSONAL_ACCESS_KEY,
155
141
  // Flows
156
- API_KEY_FLOW,
157
142
  OAUTH_FLOW,
158
143
  };
package/lib/regex.js CHANGED
@@ -1,7 +1,5 @@
1
- const API_KEY_REGEX = /^([a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12})$/i;
2
1
  const STRING_WITH_NO_SPACES_REGEX = /^\S*$/;
3
2
 
4
3
  module.exports = {
5
- API_KEY_REGEX,
6
4
  STRING_WITH_NO_SPACES_REGEX,
7
5
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "4.0.1-beta.0",
3
+ "version": "4.0.1-beta.3",
4
4
  "description": "CLI for working with HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -8,8 +8,8 @@
8
8
  "url": "https://github.com/HubSpot/hubspot-cms-tools"
9
9
  },
10
10
  "dependencies": {
11
- "@hubspot/cli-lib": "4.0.1-beta.0",
12
- "@hubspot/serverless-dev-runtime": "4.0.1-beta.0",
11
+ "@hubspot/cli-lib": "4.0.1-beta.3",
12
+ "@hubspot/serverless-dev-runtime": "4.0.1-beta.3",
13
13
  "archiver": "^5.3.0",
14
14
  "chalk": "^4.1.2",
15
15
  "express": "^4.17.1",
@@ -37,5 +37,5 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "fb23906d7f8694f9de4bb43043127a74f5b63a29"
40
+ "gitHead": "e2fac76a5ea9f51f69dfb786a5f285ffcf88a47a"
41
41
  }