@hubspot/cli 5.3.1 → 5.4.1-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 (39) hide show
  1. package/bin/cli.js +24 -5
  2. package/commands/__tests__/projects.test.js +105 -0
  3. package/commands/accounts/clean.js +1 -1
  4. package/commands/cms/convertFields.js +13 -7
  5. package/commands/project/__tests__/deploy.test.js +1 -1
  6. package/commands/project/__tests__/installDeps.test.js +168 -0
  7. package/commands/project/__tests__/logs.test.js +305 -0
  8. package/commands/project/add.js +24 -12
  9. package/commands/project/cloneApp.js +13 -21
  10. package/commands/project/deploy.js +4 -1
  11. package/commands/project/dev.js +22 -11
  12. package/commands/project/download.js +6 -3
  13. package/commands/project/installDeps.js +78 -0
  14. package/commands/project/logs.js +80 -242
  15. package/commands/project/migrateApp.js +8 -9
  16. package/commands/project/upload.js +5 -3
  17. package/commands/project/watch.js +3 -9
  18. package/commands/project.js +2 -0
  19. package/commands/sandbox/create.js +1 -0
  20. package/commands/sandbox.js +0 -2
  21. package/lang/en.lyaml +40 -75
  22. package/lib/LocalDevManager.js +1 -22
  23. package/lib/__tests__/dependencyManagement.test.js +245 -0
  24. package/lib/__tests__/projectLogsManager.test.js +210 -0
  25. package/lib/dependencyManagement.js +157 -0
  26. package/lib/errorHandlers/apiErrors.js +1 -3
  27. package/lib/errorHandlers/overrideErrors.js +57 -36
  28. package/lib/localDev.js +25 -16
  29. package/lib/projectLogsManager.js +144 -0
  30. package/lib/projects.js +17 -7
  31. package/lib/projectsWatch.js +2 -5
  32. package/lib/prompts/__tests__/projectsLogsPrompt.test.js +46 -0
  33. package/lib/prompts/createProjectPrompt.js +4 -0
  34. package/lib/prompts/projectAddPrompt.js +4 -21
  35. package/lib/prompts/projectDevTargetAccountPrompt.js +16 -25
  36. package/lib/prompts/projectsLogsPrompt.js +17 -108
  37. package/lib/sandboxSync.js +13 -15
  38. package/package.json +6 -6
  39. package/commands/sandbox/sync.js +0 -225
@@ -0,0 +1,144 @@
1
+ const { getProjectConfig, ensureProjectExists } = require('./projects');
2
+ const {
3
+ fetchProjectComponentsMetadata,
4
+ } = require('@hubspot/local-dev-lib/api/projects');
5
+ const { i18n } = require('./lang');
6
+ const { uiLink } = require('./ui');
7
+
8
+ const i18nKey = 'commands.project.subcommands.logs';
9
+
10
+ class ProjectLogsManager {
11
+ reset() {
12
+ Object.keys(this).forEach(key => {
13
+ if (Object.hasOwn(this, key)) {
14
+ this[key] = undefined;
15
+ }
16
+ });
17
+ }
18
+
19
+ async init(accountId) {
20
+ const { projectConfig } = await getProjectConfig();
21
+
22
+ if (!projectConfig || !projectConfig.name) {
23
+ throw new Error(i18n(`${i18nKey}.errors.noProjectConfig`));
24
+ }
25
+
26
+ const { name: projectName } = projectConfig;
27
+
28
+ this.projectName = projectName;
29
+ this.accountId = accountId;
30
+ this.functions = [];
31
+
32
+ const { project } = await ensureProjectExists(
33
+ this.accountId,
34
+ this.projectName,
35
+ {
36
+ allowCreate: false,
37
+ }
38
+ );
39
+
40
+ if (
41
+ !project ||
42
+ !project.deployedBuild ||
43
+ !project.deployedBuild.subbuildStatuses
44
+ ) {
45
+ throw new Error(i18n(`${i18nKey}.errors.failedToFetchProjectDetails`));
46
+ }
47
+
48
+ this.projectId = project.id;
49
+ await this.fetchFunctionDetails();
50
+ }
51
+
52
+ async fetchFunctionDetails() {
53
+ if (!this.projectId) {
54
+ throw new Error(i18n(`${i18nKey}.errors.noProjectConfig`));
55
+ }
56
+
57
+ const { topLevelComponentMetadata } = await fetchProjectComponentsMetadata(
58
+ this.accountId,
59
+ this.projectId
60
+ );
61
+
62
+ const apps = topLevelComponentMetadata.filter(componentMetadata => {
63
+ const { type } = componentMetadata;
64
+ return type && type.name === 'PRIVATE_APP';
65
+ });
66
+
67
+ if (!this.functions) {
68
+ this.functions = [];
69
+ }
70
+
71
+ apps.forEach(app => {
72
+ this.functions.push(
73
+ ...app.featureComponents.filter(
74
+ component => component.type.name === 'APP_FUNCTION'
75
+ )
76
+ );
77
+ });
78
+
79
+ if (this.functions.length === 0) {
80
+ throw new Error(
81
+ i18n(`${i18nKey}.errors.noFunctionsInProject`, {
82
+ link: uiLink(
83
+ i18n(`${i18nKey}.errors.noFunctionsLinkText`),
84
+ 'https://developers.hubspot.com/docs/platform/serverless-functions'
85
+ ),
86
+ })
87
+ );
88
+ }
89
+ }
90
+
91
+ getFunctionNames() {
92
+ if (!this.functions) {
93
+ return [];
94
+ }
95
+ return this.functions.map(
96
+ serverlessFunction => serverlessFunction.componentName
97
+ );
98
+ }
99
+
100
+ setFunction(functionName) {
101
+ if (!this.functions) {
102
+ throw new Error(
103
+ i18n(`${i18nKey}.errors.noFunctionsInProject`, {
104
+ link: uiLink(
105
+ i18n(`${i18nKey}.errors.noFunctionsLinkText`),
106
+ 'https://developers.hubspot.com/docs/platform/serverless-functions'
107
+ ),
108
+ }),
109
+ {
110
+ projectName: this.projectName,
111
+ }
112
+ );
113
+ }
114
+
115
+ this.selectedFunction = this.functions.find(
116
+ serverlessFunction => serverlessFunction.componentName === functionName
117
+ );
118
+
119
+ if (!this.selectedFunction) {
120
+ throw new Error(
121
+ i18n(`${i18nKey}.errors.noFunctionWithName`, { name: functionName })
122
+ );
123
+ }
124
+
125
+ this.functionName = functionName;
126
+
127
+ if (!this.selectedFunction.deployOutput) {
128
+ throw new Error(
129
+ i18n(`${i18nKey}.errors.functionNotDeployed`, { name: functionName })
130
+ );
131
+ }
132
+ this.appId = this.selectedFunction.deployOutput.appId;
133
+
134
+ if (this.selectedFunction.deployOutput.endpoint) {
135
+ this.endpointName = this.selectedFunction.deployOutput.endpoint.path;
136
+ this.method = this.selectedFunction.deployOutput.endpoint.method;
137
+ this.isPublicFunction = true;
138
+ } else {
139
+ this.isPublicFunction = false;
140
+ }
141
+ }
142
+ }
143
+
144
+ module.exports = new ProjectLogsManager();
package/lib/projects.js CHANGED
@@ -7,6 +7,7 @@ const findup = require('findup-sync');
7
7
  const { logger } = require('@hubspot/local-dev-lib/logger');
8
8
  const { getEnv } = require('@hubspot/local-dev-lib/config');
9
9
  const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
10
+ const { fetchFileFromRepository } = require('@hubspot/local-dev-lib/github');
10
11
  const {
11
12
  ENVIRONMENTS,
12
13
  } = require('@hubspot/local-dev-lib/constants/environments');
@@ -18,6 +19,8 @@ const {
18
19
  PROJECT_CONFIG_FILE,
19
20
  PROJECT_TASK_TYPES,
20
21
  PROJECT_ERROR_TYPES,
22
+ HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
23
+ PROJECT_COMPONENT_TYPES,
21
24
  } = require('./constants');
22
25
  const {
23
26
  createProject,
@@ -46,7 +49,6 @@ const {
46
49
  logApiErrorInstance,
47
50
  ApiErrorContext,
48
51
  } = require('./errorHandlers/apiErrors');
49
- const { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH } = require('./constants');
50
52
 
51
53
  const i18nKey = 'lib.projects';
52
54
 
@@ -285,10 +287,7 @@ const ensureProjectExists = async (
285
287
  );
286
288
  return { projectExists: true, project };
287
289
  } catch (err) {
288
- return logApiErrorInstance(
289
- err,
290
- new ApiErrorContext({ accountId, projectName })
291
- );
290
+ return logApiErrorInstance(err, new ApiErrorContext({ accountId }));
292
291
  }
293
292
  } else {
294
293
  if (!noLogs) {
@@ -310,7 +309,7 @@ const ensureProjectExists = async (
310
309
  logger.error(err.message);
311
310
  process.exit(EXIT_CODES.ERROR);
312
311
  }
313
- logApiErrorInstance(err, new ApiErrorContext({ accountId, projectName }));
312
+ logApiErrorInstance(err, new ApiErrorContext({ accountId }));
314
313
  process.exit(EXIT_CODES.ERROR);
315
314
  }
316
315
  };
@@ -570,7 +569,7 @@ const handleProjectUpload = async (
570
569
  buildId
571
570
  );
572
571
  }
573
- resolve(uploadResult);
572
+ resolve(uploadResult || {});
574
573
  })
575
574
  );
576
575
 
@@ -1002,6 +1001,16 @@ const displayWarnLogs = async (
1002
1001
  }
1003
1002
  };
1004
1003
 
1004
+ const getProjectComponentsByVersion = async projectComponentsVersion => {
1005
+ const config = await fetchFileFromRepository(
1006
+ HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
1007
+ 'config.json',
1008
+ projectComponentsVersion
1009
+ );
1010
+
1011
+ return config[PROJECT_COMPONENT_TYPES.COMPONENTS];
1012
+ };
1013
+
1005
1014
  module.exports = {
1006
1015
  writeProjectConfig,
1007
1016
  getProjectConfig,
@@ -1019,4 +1028,5 @@ module.exports = {
1019
1028
  logFeedbackMessage,
1020
1029
  createProjectComponent,
1021
1030
  displayWarnLogs,
1031
+ getProjectComponentsByVersion,
1022
1032
  };
@@ -85,10 +85,7 @@ const debounceQueueBuild = (accountId, projectName, platformVersion) => {
85
85
  logger.log(i18n(`${i18nKey}.logs.watchCancelledFromUi`));
86
86
  process.exit(0);
87
87
  } else {
88
- logApiErrorInstance(
89
- err,
90
- new ApiErrorContext({ accountId, projectName })
91
- );
88
+ logApiErrorInstance(err, new ApiErrorContext({ accountId }));
92
89
  }
93
90
 
94
91
  return;
@@ -158,7 +155,7 @@ const createNewBuild = async (accountId, projectName, platformVersion) => {
158
155
  );
159
156
  return buildId;
160
157
  } catch (err) {
161
- logApiErrorInstance(err, new ApiErrorContext({ accountId, projectName }));
158
+ logApiErrorInstance(err, new ApiErrorContext({ accountId }));
162
159
  if (
163
160
  isSpecifiedError(err, { subCategory: PROJECT_ERROR_TYPES.PROJECT_LOCKED })
164
161
  ) {
@@ -0,0 +1,46 @@
1
+ const { projectLogsPrompt } = require('../projectsLogsPrompt');
2
+
3
+ jest.mock('../promptUtils');
4
+ const { promptUser } = require('../promptUtils');
5
+ const chalk = require('chalk');
6
+
7
+ describe('prompts/projectsLogsPrompt', () => {
8
+ it('should return undefined functionName when functionChoices is nullable', async () => {
9
+ const actual = await projectLogsPrompt({ functionChoices: null });
10
+ expect(actual).toEqual({});
11
+ expect(promptUser).not.toHaveBeenCalled();
12
+ });
13
+
14
+ it('should return the functionName without prompting when there is only one functionChoice', async () => {
15
+ const functionChoice = 'this-is-the-only-function';
16
+ const { functionName } = await projectLogsPrompt({
17
+ functionChoices: [functionChoice],
18
+ });
19
+ expect(functionName).toEqual(functionChoice);
20
+ expect(promptUser).not.toHaveBeenCalled();
21
+ });
22
+
23
+ it('should prompt the user if there is more than one choice', async () => {
24
+ const functionChoices = ['choice 1', 'choice 2'];
25
+ const projectName = 'my cool project';
26
+ await projectLogsPrompt({
27
+ functionChoices,
28
+ projectName,
29
+ });
30
+
31
+ expect(promptUser).toHaveBeenCalledTimes(1);
32
+ expect(promptUser).toHaveBeenLastCalledWith(
33
+ expect.arrayContaining([
34
+ expect.objectContaining({
35
+ name: 'functionName',
36
+ type: 'list',
37
+ message: `[--function] Select function in ${chalk.bold(
38
+ projectName
39
+ )} project`,
40
+ when: expect.any(Function),
41
+ choices: functionChoices,
42
+ }),
43
+ ])
44
+ );
45
+ });
46
+ });
@@ -4,6 +4,7 @@ const {
4
4
  getCwd,
5
5
  sanitizeFileName,
6
6
  isValidPath,
7
+ untildify,
7
8
  } = require('@hubspot/local-dev-lib/path');
8
9
  const { PROJECT_COMPONENT_TYPES } = require('../../lib/constants');
9
10
  const { promptUser } = require('./promptUtils');
@@ -100,6 +101,9 @@ const createProjectPrompt = async (
100
101
  }
101
102
  return true;
102
103
  },
104
+ filter: input => {
105
+ return untildify(input);
106
+ },
103
107
  },
104
108
  {
105
109
  name: 'template',
@@ -1,32 +1,15 @@
1
1
  const { promptUser } = require('./promptUtils');
2
- const { fetchFileFromRepository } = require('@hubspot/local-dev-lib/github');
3
2
  const { i18n } = require('../lang');
4
- const { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH } = require('../constants');
5
- const { PROJECT_COMPONENT_TYPES } = require('../constants');
6
3
 
7
4
  const i18nKey = 'lib.prompts.projectAddPrompt';
8
5
 
9
- const createTypeOptions = async projectComponentsVersion => {
10
- const config = await fetchFileFromRepository(
11
- HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH,
12
- 'config.json',
13
- projectComponentsVersion
14
- );
15
-
16
- return config[PROJECT_COMPONENT_TYPES.COMPONENTS];
17
- };
18
-
19
- const projectAddPrompt = async (
20
- projectComponentsVersion,
21
- promptOptions = {}
22
- ) => {
23
- const components = await createTypeOptions(projectComponentsVersion);
6
+ const projectAddPrompt = async (components, promptOptions = {}) => {
24
7
  return promptUser([
25
8
  {
26
- name: 'type',
9
+ name: 'component',
27
10
  message: () => {
28
11
  return promptOptions.type &&
29
- !components.find(t => t.path === promptOptions.type.path)
12
+ !components.find(t => t.path === promptOptions.type)
30
13
  ? i18n(`${i18nKey}.errors.invalidType`, {
31
14
  type: promptOptions.type,
32
15
  })
@@ -34,7 +17,7 @@ const projectAddPrompt = async (
34
17
  },
35
18
  when:
36
19
  !promptOptions.type ||
37
- !components.find(t => t.path === promptOptions.type.path),
20
+ !components.find(t => t.path === promptOptions.type),
38
21
  type: 'list',
39
22
  choices: components.map(type => {
40
23
  return {
@@ -1,7 +1,7 @@
1
1
  const { promptUser } = require('./promptUtils');
2
2
  const { i18n } = require('../lang');
3
3
  const { uiAccountDescription, uiCommandReference } = require('../ui');
4
- const { isSandbox, isDeveloperTestAccount } = require('../accountTypes');
4
+ const { isSandbox } = require('../accountTypes');
5
5
  const { getAccountId } = require('@hubspot/local-dev-lib/config');
6
6
  const { getSandboxUsageLimits } = require('@hubspot/local-dev-lib/sandboxes');
7
7
  const {
@@ -99,7 +99,6 @@ const selectDeveloperTestTargetAccountPrompt = async (
99
99
  defaultAccountConfig
100
100
  ) => {
101
101
  const defaultAccountId = getAccountId(defaultAccountConfig.name);
102
- let choices = [];
103
102
  let devTestAccountsResponse = undefined;
104
103
  try {
105
104
  devTestAccountsResponse = await fetchDeveloperTestAccounts(
@@ -109,13 +108,6 @@ const selectDeveloperTestTargetAccountPrompt = async (
109
108
  logger.debug('Unable to fetch developer test account usage limits: ', err);
110
109
  }
111
110
 
112
- const devTestAccounts = accounts
113
- .reverse()
114
- .filter(
115
- config =>
116
- isDeveloperTestAccount(config) &&
117
- config.parentAccountId === defaultAccountId
118
- );
119
111
  let disabledMessage = false;
120
112
  if (
121
113
  devTestAccountsResponse &&
@@ -128,27 +120,26 @@ const selectDeveloperTestTargetAccountPrompt = async (
128
120
  });
129
121
  }
130
122
 
131
- let devTestAccountsNotInConfig = [];
123
+ const devTestAccounts = [];
132
124
  if (devTestAccountsResponse && devTestAccountsResponse.results) {
133
- const inConfigIds = devTestAccounts.map(d => d.portalId);
125
+ const accountIds = accounts.map(account => account.portalId);
126
+
134
127
  devTestAccountsResponse.results.forEach(acct => {
135
- if (inConfigIds.indexOf(acct.id) < 0) {
136
- devTestAccountsNotInConfig.push({
137
- name: getNonConfigDeveloperTestAccountName(acct),
138
- value: {
139
- targetAccountId: acct.id,
140
- createdNestedAccount: false,
141
- parentAccountId: defaultAccountId,
142
- notInConfigAccount: acct,
143
- },
144
- });
145
- }
128
+ const inConfig = accountIds.includes(acct.id);
129
+ devTestAccounts.push({
130
+ name: getNonConfigDeveloperTestAccountName(acct),
131
+ value: {
132
+ targetAccountId: acct.id,
133
+ createdNestedAccount: false,
134
+ parentAccountId: defaultAccountId,
135
+ notInConfigAccount: inConfig ? null : acct,
136
+ },
137
+ });
146
138
  });
147
139
  }
148
140
 
149
- choices = [
150
- ...devTestAccounts.map(mapNestedAccount),
151
- ...devTestAccountsNotInConfig,
141
+ const choices = [
142
+ ...devTestAccounts,
152
143
  {
153
144
  name: i18n(`${i18nKey}.createNewDeveloperTestAccountOption`),
154
145
  value: {
@@ -1,120 +1,29 @@
1
1
  const { i18n } = require('../lang');
2
- const { fetchProject } = require('@hubspot/local-dev-lib/api/projects');
3
2
  const { promptUser } = require('./promptUtils');
4
- const { getAccountId } = require('../commonOpts');
5
- const { getProjectConfig, ensureProjectExists } = require('../projects');
6
- const {
7
- logApiErrorInstance,
8
- ApiErrorContext,
9
- } = require('../../lib/errorHandlers/apiErrors');
10
- const { logger } = require('@hubspot/local-dev-lib/logger');
11
- const { EXIT_CODES } = require('../enums/exitCodes');
12
3
 
13
4
  const i18nKey = 'lib.prompts.projectLogsPrompt';
14
5
 
15
- const SERVERLESS_FUNCTION_TYPES = {
16
- APP_FUNCTION: 'app-function',
17
- PUBLIC_ENDPOINT: 'public-endpoint',
18
- };
6
+ const projectLogsPrompt = async ({
7
+ functionChoices,
8
+ promptOptions,
9
+ projectName = {},
10
+ }) => {
11
+ if (!functionChoices) {
12
+ return {};
13
+ }
14
+ if (functionChoices && functionChoices.length === 1) {
15
+ return { functionName: functionChoices[0] };
16
+ }
19
17
 
20
- const projectLogsPrompt = (accountId, promptOptions = {}) => {
21
18
  return promptUser([
22
- {
23
- name: 'projectName',
24
- message: i18n(`${i18nKey}.projectName.message`),
25
- when: !promptOptions.project,
26
- default: async () => {
27
- const { projectConfig } = await getProjectConfig();
28
- return projectConfig && projectConfig.name ? projectConfig.name : null;
29
- },
30
- validate: name =>
31
- !name.length ? i18n(`${i18nKey}.projectName.error`) : true,
32
- },
33
- {
34
- name: 'logType',
35
- type: 'list',
36
- message: i18n(`${i18nKey}.logType.message`),
37
- when:
38
- !promptOptions.app &&
39
- !promptOptions.function &&
40
- !promptOptions.endpoint,
41
- choices: [
42
- {
43
- name: i18n(`${i18nKey}.logType.function`),
44
- value: SERVERLESS_FUNCTION_TYPES.APP_FUNCTION,
45
- },
46
- {
47
- name: i18n(`${i18nKey}.logType.endpoint`),
48
- value: SERVERLESS_FUNCTION_TYPES.PUBLIC_ENDPOINT,
49
- },
50
- ],
51
- },
52
- {
53
- name: 'appName',
54
- type: 'list',
55
- message: i18n(`${i18nKey}.appName`),
56
- when: ({ logType }) => {
57
- return (
58
- (promptOptions.function ||
59
- logType === SERVERLESS_FUNCTION_TYPES.APP_FUNCTION) &&
60
- !promptOptions.app &&
61
- !promptOptions.endpoint
62
- );
63
- },
64
- choices: async ({ projectName }) => {
65
- const name = projectName || promptOptions.project;
66
-
67
- try {
68
- await ensureProjectExists(accountId, name, {
69
- allowCreate: false,
70
- });
71
- const { deployedBuild } = await fetchProject(accountId, name);
72
-
73
- if (deployedBuild && deployedBuild.subbuildStatuses) {
74
- return deployedBuild.subbuildStatuses
75
- .filter(subbuild => subbuild.buildType === 'PRIVATE_APP')
76
- .map(subbuild => ({
77
- name: subbuild.buildName,
78
- value: subbuild.buildName,
79
- }));
80
- } else {
81
- logger.debug('Failed to fetch project');
82
- process.exit(EXIT_CODES.ERROR);
83
- }
84
- } catch (e) {
85
- const { projectConfig } = await getProjectConfig();
86
- const projectName = projectConfig.name;
87
-
88
- logApiErrorInstance(
89
- e,
90
- new ApiErrorContext({ accountId: getAccountId(), projectName })
91
- );
92
- process.exit(EXIT_CODES.ERROR);
93
- }
94
- },
95
- },
96
19
  {
97
20
  name: 'functionName',
98
- message: i18n(`${i18nKey}.functionName`),
99
- when: ({ logType }) => {
100
- return (
101
- (promptOptions.app ||
102
- logType === SERVERLESS_FUNCTION_TYPES.APP_FUNCTION) &&
103
- !promptOptions.function &&
104
- !promptOptions.endpoint
105
- );
106
- },
107
- },
108
- {
109
- name: 'endpointName',
110
- message: i18n(`${i18nKey}.endpointName`),
111
- when: ({ logType }) => {
112
- return (
113
- logType === SERVERLESS_FUNCTION_TYPES.PUBLIC_ENDPOINT &&
114
- !promptOptions.function &&
115
- !promptOptions.endpoint
116
- );
117
- },
21
+ type: 'list',
22
+ message: i18n(`${i18nKey}.functionName`, { projectName }),
23
+ when: () =>
24
+ (!promptOptions || !promptOptions.function) &&
25
+ functionChoices.length > 0,
26
+ choices: functionChoices,
118
27
  },
119
28
  ]);
120
29
  };
@@ -4,14 +4,12 @@ const { logger } = require('@hubspot/local-dev-lib/logger');
4
4
  const { i18n } = require('./lang');
5
5
  const { getAvailableSyncTypes } = require('./sandboxes');
6
6
  const { initiateSync } = require('@hubspot/local-dev-lib/sandboxes');
7
+ const { debugErrorAndContext } = require('./errorHandlers/standardErrors');
7
8
  const {
8
- debugErrorAndContext,
9
- logErrorInstance,
10
- } = require('./errorHandlers/standardErrors');
11
- const {
12
- isSpecifiedError,
13
- isMissingScopeError,
14
- } = require('@hubspot/local-dev-lib/errors/apiErrors');
9
+ logApiErrorInstance,
10
+ ApiErrorContext,
11
+ } = require('./errorHandlers/apiErrors');
12
+ const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/apiErrors');
15
13
  const { getSandboxTypeAsString } = require('./sandboxes');
16
14
  const { getAccountId } = require('@hubspot/local-dev-lib/config');
17
15
  const {
@@ -97,13 +95,7 @@ const syncSandbox = async ({
97
95
  });
98
96
 
99
97
  logger.log('');
100
- if (isMissingScopeError(err)) {
101
- logger.error(
102
- i18n(`${i18nKey}.failure.missingScopes`, {
103
- accountName: uiAccountDescription(parentAccountId),
104
- })
105
- );
106
- } else if (
98
+ if (
107
99
  isSpecifiedError(err, {
108
100
  statusCode: 403,
109
101
  category: 'BANNED',
@@ -163,7 +155,13 @@ const syncSandbox = async ({
163
155
  'https://app.hubspot.com/l/docs/guides/crm/project-cli-commands#developer-projects-cli-commands-beta'
164
156
  );
165
157
  } else {
166
- logErrorInstance(err);
158
+ logApiErrorInstance(
159
+ err,
160
+ new ApiErrorContext({
161
+ accountId: parentAccountId,
162
+ request: 'sandbox sync',
163
+ })
164
+ );
167
165
  }
168
166
  logger.log('');
169
167
  throw err;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "5.3.1",
3
+ "version": "5.4.1-beta.0",
4
4
  "description": "CLI for working with HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -8,10 +8,10 @@
8
8
  "url": "https://github.com/HubSpot/hubspot-cms-tools"
9
9
  },
10
10
  "dependencies": {
11
- "@hubspot/local-dev-lib": "1.10.0",
12
- "@hubspot/serverless-dev-runtime": "5.3.0",
11
+ "@hubspot/local-dev-lib": "1.13.0",
12
+ "@hubspot/serverless-dev-runtime": "5.4.1-beta.0",
13
13
  "@hubspot/theme-preview-dev-server": "0.0.7",
14
- "@hubspot/ui-extensions-dev-server": "0.8.20",
14
+ "@hubspot/ui-extensions-dev-server": "0.8.33",
15
15
  "archiver": "^5.3.0",
16
16
  "chalk": "^4.1.2",
17
17
  "chokidar": "^3.0.1",
@@ -37,7 +37,7 @@
37
37
  "mock-stdin": "^1.0.0"
38
38
  },
39
39
  "engines": {
40
- "node": ">=16"
40
+ "node": ">=18"
41
41
  },
42
42
  "bin": {
43
43
  "hs": "./bin/hs",
@@ -46,5 +46,5 @@
46
46
  "publishConfig": {
47
47
  "access": "public"
48
48
  },
49
- "gitHead": "f66f8d19cc041132fb985b56156eed2511d9a588"
49
+ "gitHead": "bce14e5b832d387f2d1166a587c57f50242a65d7"
50
50
  }