@hubspot/cli 5.2.0 → 5.2.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.
@@ -62,10 +62,10 @@ const { getHubSpotWebsiteOrigin } = require('@hubspot/local-dev-lib/urls');
62
62
  const {
63
63
  logApiErrorInstance,
64
64
  ApiErrorContext,
65
- isSpecifiedError, // Migrate isSpecifiedError to local-dev-lib version only after uploadProject is migrated to local-dev-lib
66
65
  } = require('../../lib/errorHandlers/apiErrors');
67
66
  const {
68
67
  isMissingScopeError,
68
+ isSpecifiedError,
69
69
  } = require('@hubspot/local-dev-lib/errors/apiErrors');
70
70
  const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors');
71
71
  const { isDeveloperTestAccount } = require('../../lib/developerTestAccounts');
@@ -19,11 +19,11 @@ const {
19
19
  } = require('../../lib/projects');
20
20
  const { i18n } = require('../../lib/lang');
21
21
  const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
22
+ const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/apiErrors');
22
23
  const { PROJECT_ERROR_TYPES } = require('../../lib/constants');
23
24
  const {
24
25
  logApiErrorInstance,
25
26
  ApiErrorContext,
26
- isSpecifiedError,
27
27
  } = require('../../lib/errorHandlers/apiErrors');
28
28
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
29
29
 
@@ -1,7 +1,10 @@
1
1
  const { logger } = require('@hubspot/local-dev-lib/logger');
2
2
  const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
3
3
  const {
4
+ isMissingScopeError,
5
+ isApiUploadValidationError,
4
6
  getAxiosErrorWithContext,
7
+ parseValidationErrors,
5
8
  } = require('@hubspot/local-dev-lib/errors/apiErrors');
6
9
  const {
7
10
  SCOPE_GROUPS,
@@ -18,80 +21,6 @@ const { i18n } = require('../lang');
18
21
 
19
22
  const i18nKey = 'cli.lib.errorHandlers.apiErrors';
20
23
 
21
- const isApiStatusCodeError = err =>
22
- err.name === 'StatusCodeError' ||
23
- (err.statusCode >= 100 && err.statusCode < 600);
24
-
25
- const isApiUploadValidationError = err =>
26
- !!(
27
- err.statusCode === 400 &&
28
- err.response &&
29
- err.response.body &&
30
- (err.response.body.message || err.response.body.errors)
31
- );
32
-
33
- const isMissingScopeError = err =>
34
- err.name === 'StatusCodeError' &&
35
- err.statusCode === 403 &&
36
- err.error &&
37
- err.error.category === 'MISSING_SCOPES';
38
-
39
- const isGatingError = err =>
40
- isSpecifiedError(err, { statusCode: 403, category: 'GATED' });
41
-
42
- const isSpecifiedError = (err, { statusCode, category, subCategory } = {}) => {
43
- const statusCodeErr = !statusCode || err.statusCode === statusCode;
44
- const categoryErr =
45
- !category || (err.error && err.error.category === category);
46
- const subCategoryErr =
47
- !subCategory || (err.error && err.error.subCategory === subCategory);
48
-
49
- return (
50
- err.name === 'StatusCodeError' &&
51
- statusCodeErr &&
52
- categoryErr &&
53
- subCategoryErr
54
- );
55
- };
56
-
57
- const isSpecifiedHubSpotAuthError = (
58
- err,
59
- { statusCode, category, subCategory }
60
- ) => {
61
- const statusCodeErr = !statusCode || err.statusCode === statusCode;
62
- const categoryErr = !category || err.category === category;
63
- const subCategoryErr = !subCategory || err.subCategory === subCategory;
64
- return (
65
- err.name === 'HubSpotAuthError' &&
66
- statusCodeErr &&
67
- categoryErr &&
68
- subCategoryErr
69
- );
70
- };
71
-
72
- const parseValidationErrors = (responseBody = {}) => {
73
- const errorMessages = [];
74
-
75
- const { errors, message } = responseBody;
76
-
77
- if (message) {
78
- errorMessages.push(message);
79
- }
80
-
81
- if (errors) {
82
- const specificErrors = errors.map(error => {
83
- let errorMessage = error.message;
84
- if (error.errorTokens && error.errorTokens.line) {
85
- errorMessage = `line ${error.errorTokens.line}: ${errorMessage}`;
86
- }
87
- return errorMessage;
88
- });
89
- errorMessages.push(...specificErrors);
90
- }
91
-
92
- return errorMessages;
93
- };
94
-
95
24
  class ApiErrorContext extends ErrorContext {
96
25
  constructor(props = {}) {
97
26
  super(props);
@@ -110,139 +39,10 @@ class ApiErrorContext extends ErrorContext {
110
39
  */
111
40
  function logValidationErrors(error, context) {
112
41
  const { response = {} } = error;
113
- const validationErrors = parseValidationErrors(response.body);
42
+ const validationErrors = parseValidationErrors(response.data);
114
43
  if (validationErrors.length) {
115
- validationErrors.forEach(err => {
116
- logger.error(err);
117
- });
118
- }
119
- debugErrorAndContext(error, context);
120
- }
121
-
122
- /**
123
- * Message segments for API messages.
124
- *
125
- * @enum {string}
126
- */
127
- const ApiMethodVerbs = {
128
- DEFAULT: 'request',
129
- DELETE: 'delete',
130
- GET: 'request',
131
- PATCH: 'update',
132
- POST: 'post',
133
- PUT: 'update',
134
- };
135
-
136
- /**
137
- * Message segments for API messages.
138
- *
139
- * @enum {string}
140
- */
141
- const ApiMethodPrepositions = {
142
- DEFAULT: 'for',
143
- DELETE: 'of',
144
- GET: 'for',
145
- PATCH: 'to',
146
- POST: 'to',
147
- PUT: 'to',
148
- };
149
-
150
- /**
151
- * Logs messages for an error instance resulting from API interaction.
152
- *
153
- * @param {StatusCodeError} error
154
- * @param {ApiErrorContext} context
155
- */
156
- function logApiStatusCodeError(error, context) {
157
- const { statusCode } = error;
158
- const { method } = error.options || {};
159
- const { projectName } = context;
160
- const isPutOrPost = method === 'PUT' || method === 'POST';
161
- const action = ApiMethodVerbs[method] || ApiMethodVerbs.DEFAULT;
162
- const preposition =
163
- ApiMethodPrepositions[method] || ApiMethodPrepositions.DEFAULT;
164
- let messageDetail = '';
165
- {
166
- const request = context.request
167
- ? `${action} ${preposition} "${context.request}"`
168
- : action;
169
- messageDetail = `${request} in account ${context.accountId}`;
170
- }
171
- const errorMessage = [];
172
- if (isPutOrPost && context.payload) {
173
- errorMessage.push(`Unable to upload "${context.payload}".`);
174
- }
175
- const isProjectMissingScopeError = isMissingScopeError(error) && projectName;
176
- const isProjectGatingError = isGatingError(error) && projectName;
177
- switch (statusCode) {
178
- case 400:
179
- errorMessage.push(i18n(`${i18nKey}.codes.400`, { messageDetail }));
180
- break;
181
- case 401:
182
- errorMessage.push(i18n(`${i18nKey}.codes.401`, { messageDetail }));
183
- break;
184
- case 403:
185
- if (isProjectMissingScopeError) {
186
- errorMessage.push(
187
- i18n(`${i18nKey}.codes.403MissingScope`, {
188
- accountId: context.accountId || '',
189
- })
190
- );
191
- } else if (isProjectGatingError) {
192
- errorMessage.push(
193
- i18n(`${i18nKey}.codes.403Gating`, {
194
- accountId: context.accountId || '',
195
- })
196
- );
197
- } else {
198
- errorMessage.push(i18n(`${i18nKey}.codes.403`, { messageDetail }));
199
- }
200
- break;
201
- case 404:
202
- if (context.request) {
203
- errorMessage.push(
204
- i18n(`${i18nKey}.codes.404Request`, {
205
- action: action || 'request',
206
- request: context.request,
207
- account: context.accountId || '',
208
- })
209
- );
210
- } else {
211
- errorMessage.push(i18n(`${i18nKey}.codes.404`, { messageDetail }));
212
- }
213
- break;
214
- case 429:
215
- errorMessage.push(i18n(`${i18nKey}.codes.429`, { messageDetail }));
216
- break;
217
- case 503:
218
- errorMessage.push(i18n(`${i18nKey}.codes.503`, { messageDetail }));
219
- break;
220
- default:
221
- if (statusCode >= 500 && statusCode < 600) {
222
- errorMessage.push(
223
- i18n(`${i18nKey}.codes.500Generic`, { messageDetail })
224
- );
225
- } else if (statusCode >= 400 && statusCode < 500) {
226
- i18n(`${i18nKey}.codes.400Generic`, { messageDetail });
227
- } else {
228
- errorMessage.push(i18n(`${i18nKey}.codes.generic`, { messageDetail }));
229
- }
230
- break;
44
+ logger.error(validationErrors.join('\n- '));
231
45
  }
232
- if (
233
- error.error &&
234
- error.error.message &&
235
- !isProjectMissingScopeError &&
236
- !isProjectGatingError
237
- ) {
238
- errorMessage.push(error.error.message);
239
- }
240
- if (error.error && error.error.errors) {
241
- error.error.errors.forEach(err => {
242
- errorMessage.push('\n- ' + err.message);
243
- });
244
- }
245
- logger.error(errorMessage.join(' '));
246
46
  debugErrorAndContext(error, context);
247
47
  }
248
48
 
@@ -253,19 +53,12 @@ function logApiStatusCodeError(error, context) {
253
53
  * @param {ApiErrorContext} context
254
54
  */
255
55
  function logApiErrorInstance(error, context) {
256
- // Use the new local-dev-lib error handler
257
- // NOTE: This will eventually replace the logic in logApiStatusCodeError
258
56
  if (error.isAxiosError) {
259
57
  if (overrideErrors(error)) return;
260
58
  const errorWithContext = getAxiosErrorWithContext(error, context);
261
59
  logger.error(errorWithContext.message);
262
60
  return;
263
61
  }
264
- // StatusCodeError
265
- if (isApiStatusCodeError(error)) {
266
- logApiStatusCodeError(error, context);
267
- return;
268
- }
269
62
  logErrorInstance(error, context);
270
63
  }
271
64
 
@@ -342,12 +135,7 @@ async function logServerlessFunctionApiErrorInstance(
342
135
  return;
343
136
  }
344
137
 
345
- // StatusCodeError
346
- if (isApiStatusCodeError(error)) {
347
- logApiStatusCodeError(error, context);
348
- return;
349
- }
350
- logErrorInstance(error, context);
138
+ logApiErrorInstance(error, context);
351
139
  }
352
140
 
353
141
  module.exports = {
@@ -356,7 +144,4 @@ module.exports = {
356
144
  logApiErrorInstance,
357
145
  logApiUploadErrorInstance,
358
146
  logServerlessFunctionApiErrorInstance,
359
- isMissingScopeError,
360
- isSpecifiedError,
361
- isSpecifiedHubSpotAuthError,
362
147
  };
@@ -1,24 +1,7 @@
1
- const { logger } = require('@hubspot/local-dev-lib/logger');
2
1
  const {
3
- ErrorContext,
4
- isSystemError,
5
- debugErrorAndContext,
6
- } = require('./standardErrors');
7
- const { i18n } = require('../lang');
8
-
9
- const i18nKey = 'cli.lib.errorHandlers.fileSystemErrors';
10
-
11
- class FileSystemErrorContext extends ErrorContext {
12
- constructor(props = {}) {
13
- super(props);
14
- /** @type {string} */
15
- this.filepath = props.filepath || '';
16
- /** @type {boolean} */
17
- this.read = !!props.read;
18
- /** @type {boolean} */
19
- this.write = !!props.write;
20
- }
21
- }
2
+ getFileSystemError,
3
+ } = require('@hubspot/local-dev-lib/errors/fileSystemErrors');
4
+ const { debugErrorAndContext, logErrorInstance } = require('./standardErrors');
22
5
 
23
6
  /**
24
7
  * Logs a message for an error instance resulting from filesystem interaction.
@@ -27,29 +10,11 @@ class FileSystemErrorContext extends ErrorContext {
27
10
  * @param {FileSystemErrorContext} context
28
11
  */
29
12
  function logFileSystemErrorInstance(error, context) {
30
- let fileAction = '';
31
- if (context.read) {
32
- fileAction = 'reading from';
33
- } else if (context.write) {
34
- fileAction = 'writing to';
35
- } else {
36
- fileAction = 'accessing';
37
- }
38
- const filepath = context.filepath
39
- ? `"${context.filepath}"`
40
- : 'a file or folder';
41
- const message = [i18n(`${i18nKey}.errorOccurred`, { fileAction, filepath })];
42
- // Many `fs` errors will be `SystemError`s
43
- if (isSystemError(error)) {
44
- message.push(
45
- i18n(`${i18nKey}.errorExplanation`, { errorMessage: error.message })
46
- );
47
- }
48
- logger.error(message.join(' '));
13
+ const fileSystemError = getFileSystemError(error, context);
14
+ logErrorInstance(fileSystemError.message, context);
49
15
  debugErrorAndContext(error, context);
50
16
  }
51
17
 
52
18
  module.exports = {
53
- FileSystemErrorContext,
54
19
  logFileSystemErrorInstance,
55
20
  };
@@ -1,16 +1,12 @@
1
1
  const util = require('util');
2
- const {
3
- HubSpotAuthError,
4
- } = require('@hubspot/local-dev-lib/models/HubSpotAuthError');
5
2
  const { logger } = require('@hubspot/local-dev-lib/logger');
3
+ const {
4
+ isSystemError,
5
+ } = require('@hubspot/local-dev-lib/errors/standardErrors');
6
6
  const { i18n } = require('../lang');
7
7
 
8
8
  const i18nKey = 'cli.lib.errorHandlers.standardErrors';
9
9
 
10
- const isSystemError = err =>
11
- err.errno != null && err.code != null && err.syscall != null;
12
- const isFatalError = err => err instanceof HubSpotAuthError;
13
-
14
10
  // TODO: Make these TS interfaces
15
11
  class ErrorContext {
16
12
  constructor(props = {}) {
@@ -103,7 +99,5 @@ function logErrorInstance(error, context) {
103
99
  module.exports = {
104
100
  debugErrorAndContext,
105
101
  ErrorContext,
106
- isFatalError,
107
- isSystemError,
108
102
  logErrorInstance,
109
103
  };
package/lib/projects.js CHANGED
@@ -27,7 +27,10 @@ const {
27
27
  fetchProject,
28
28
  uploadProject,
29
29
  } = require('@hubspot/local-dev-lib/api/projects');
30
- const { isSpecifiedError } = require('@hubspot/local-dev-lib/errors/apiErrors');
30
+ const {
31
+ isSpecifiedError,
32
+ isSpecifiedHubSpotAuthError,
33
+ } = require('@hubspot/local-dev-lib/errors/apiErrors');
31
34
  const { shouldIgnoreFile } = require('@hubspot/local-dev-lib/ignoreRules');
32
35
  const { getCwd, getAbsoluteFilePath } = require('@hubspot/local-dev-lib/path');
33
36
  const { downloadGithubRepoContents } = require('@hubspot/local-dev-lib/github');
@@ -39,7 +42,6 @@ const SpinniesManager = require('./ui/SpinniesManager');
39
42
  const {
40
43
  logApiErrorInstance,
41
44
  ApiErrorContext,
42
- isSpecifiedHubSpotAuthError,
43
45
  } = require('./errorHandlers/apiErrors');
44
46
  const { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH } = require('./constants');
45
47
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "5.2.0",
3
+ "version": "5.2.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": "^0.3.10",
12
- "@hubspot/serverless-dev-runtime": "5.1.4-beta.6",
11
+ "@hubspot/local-dev-lib": "^0.3.13",
12
+ "@hubspot/serverless-dev-runtime": "5.2.1-beta.0",
13
13
  "@hubspot/theme-preview-dev-server": "0.0.4",
14
- "@hubspot/ui-extensions-dev-server": "0.8.11",
14
+ "@hubspot/ui-extensions-dev-server": "0.8.12",
15
15
  "archiver": "^5.3.0",
16
16
  "chalk": "^4.1.2",
17
17
  "chokidar": "^3.0.1",
@@ -45,5 +45,5 @@
45
45
  "publishConfig": {
46
46
  "access": "public"
47
47
  },
48
- "gitHead": "b617fec2c05af70815192d7a41127d90f5c6b6d2"
48
+ "gitHead": "ce6013a55ac84a69335200abbcbc6fc8080585b7"
49
49
  }