@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.
package/commands/project/dev.js
CHANGED
|
@@ -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.
|
|
42
|
+
const validationErrors = parseValidationErrors(response.data);
|
|
114
43
|
if (validationErrors.length) {
|
|
115
|
-
validationErrors.
|
|
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
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
31
|
-
|
|
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 {
|
|
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.
|
|
12
|
-
"@hubspot/serverless-dev-runtime": "5.1
|
|
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.
|
|
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": "
|
|
48
|
+
"gitHead": "ce6013a55ac84a69335200abbcbc6fc8080585b7"
|
|
49
49
|
}
|