@hubspot/local-dev-lib 1.13.0 → 2.0.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/api/appsDev.d.ts +6 -5
- package/api/appsDev.js +6 -10
- package/api/customObjects.d.ts +7 -6
- package/api/customObjects.js +13 -16
- package/api/designManager.d.ts +3 -2
- package/api/designManager.js +5 -8
- package/api/developerTestAccounts.d.ts +5 -4
- package/api/developerTestAccounts.js +9 -10
- package/api/fileManager.d.ts +5 -4
- package/api/fileManager.js +9 -9
- package/api/fileMapper.d.ts +8 -8
- package/api/fileMapper.js +16 -16
- package/api/fileTransport.d.ts +4 -3
- package/api/fileTransport.js +5 -5
- package/api/functions.d.ts +6 -5
- package/api/functions.js +11 -14
- package/api/github.d.ts +6 -6
- package/api/github.js +5 -5
- package/api/hubdb.d.ts +9 -8
- package/api/hubdb.js +17 -20
- package/api/lighthouseScore.d.ts +4 -3
- package/api/lighthouseScore.js +7 -10
- package/api/localDevAuth.d.ts +5 -4
- package/api/localDevAuth.js +8 -9
- package/api/marketplaceValidation.d.ts +4 -3
- package/api/marketplaceValidation.js +4 -7
- package/api/projects.d.ts +31 -30
- package/api/projects.js +52 -52
- package/api/sandboxHubs.d.ts +5 -4
- package/api/sandboxHubs.js +9 -10
- package/api/sandboxSync.d.ts +4 -4
- package/api/sandboxSync.js +5 -14
- package/api/secrets.d.ts +5 -4
- package/api/secrets.js +9 -12
- package/api/validateHubl.d.ts +2 -1
- package/api/validateHubl.js +3 -6
- package/config/CLIConfiguration.d.ts +3 -3
- package/config/CLIConfiguration.js +22 -20
- package/config/configFile.js +7 -14
- package/config/config_DEPRECATED.js +5 -2
- package/config/index.js +45 -48
- package/errors/errors_DEPRECATED.js +2 -2
- package/errors/index.d.ts +18 -0
- package/errors/index.js +63 -0
- package/http/addQueryParams.d.ts +2 -0
- package/http/addQueryParams.js +14 -0
- package/http/getAxiosConfig.d.ts +2 -2
- package/http/getAxiosConfig.js +10 -2
- package/http/index.d.ts +9 -14
- package/http/index.js +28 -53
- package/http/unauthed.d.ts +15 -0
- package/http/unauthed.js +38 -0
- package/lang/en.json +2 -2
- package/lang/lang/en.json +2 -2
- package/lib/archive.js +11 -10
- package/lib/cms/functions.js +18 -17
- package/lib/cms/handleFieldsJS.js +8 -7
- package/lib/cms/modules.js +4 -5
- package/lib/cms/processFieldsJs.js +8 -7
- package/lib/cms/templates.js +2 -3
- package/lib/cms/uploadFolder.js +16 -14
- package/lib/cms/validate.js +1 -1
- package/lib/cms/watch.js +16 -9
- package/lib/customObjects.js +4 -15
- package/lib/fileManager.js +22 -21
- package/lib/fileMapper.js +24 -31
- package/lib/fs.js +2 -2
- package/lib/github.js +21 -21
- package/lib/gitignore.js +2 -2
- package/lib/hubdb.d.ts +3 -2
- package/lib/hubdb.js +11 -9
- package/lib/notify.js +2 -2
- package/lib/oauth.d.ts +1 -1
- package/lib/oauth.js +8 -17
- package/lib/personalAccessKey.js +16 -21
- package/lib/portManager.js +2 -2
- package/lib/trackUsage.js +12 -6
- package/models/FileSystemError.d.ts +6 -0
- package/models/FileSystemError.js +47 -0
- package/models/HubSpotHttpError.d.ts +24 -0
- package/models/HubSpotHttpError.js +197 -0
- package/models/OAuth2Manager.d.ts +1 -2
- package/models/OAuth2Manager.js +13 -28
- package/package.json +2 -1
- package/types/Error.d.ts +7 -5
- package/types/Files.d.ts +4 -4
- package/types/Http.d.ts +6 -10
- package/types/Sandbox.d.ts +0 -5
- package/utils/PortManagerServer.d.ts +3 -3
- package/utils/PortManagerServer.js +9 -9
- package/utils/cms/modules.js +2 -2
- package/utils/detectPort.js +3 -3
- package/errors/apiErrors.d.ts +0 -25
- package/errors/apiErrors.js +0 -176
- package/errors/fileSystemErrors.d.ts +0 -6
- package/errors/fileSystemErrors.js +0 -35
- package/errors/standardErrors.d.ts +0 -20
- package/errors/standardErrors.js +0 -62
- package/lib/developerTestAccounts.d.ts +0 -4
- package/lib/developerTestAccounts.js +0 -35
- package/lib/sandboxes.d.ts +0 -14
- package/lib/sandboxes.js +0 -70
- package/models/HubSpotAuthError.d.ts +0 -12
- package/models/HubSpotAuthError.js +0 -20
package/lib/hubdb.js
CHANGED
|
@@ -9,11 +9,11 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
9
9
|
const prettier_1 = __importDefault(require("prettier"));
|
|
10
10
|
const hubdb_1 = require("../api/hubdb");
|
|
11
11
|
const path_2 = require("./path");
|
|
12
|
-
const
|
|
12
|
+
const lang_1 = require("../utils/lang");
|
|
13
13
|
const i18nKey = 'lib.hubdb';
|
|
14
14
|
function validateJsonPath(src) {
|
|
15
15
|
if (path_1.default.extname(src) !== '.json') {
|
|
16
|
-
(0,
|
|
16
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidJsonPath`));
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
function validateJsonFile(src) {
|
|
@@ -22,10 +22,12 @@ function validateJsonFile(src) {
|
|
|
22
22
|
stats = fs_extra_1.default.statSync(src);
|
|
23
23
|
}
|
|
24
24
|
catch (err) {
|
|
25
|
-
(0,
|
|
25
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidJsonFile`, { src }), {
|
|
26
|
+
cause: err,
|
|
27
|
+
});
|
|
26
28
|
}
|
|
27
29
|
if (!stats.isFile()) {
|
|
28
|
-
(0,
|
|
30
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidJsonFile`, { src }));
|
|
29
31
|
}
|
|
30
32
|
validateJsonPath(src);
|
|
31
33
|
}
|
|
@@ -42,7 +44,7 @@ async function addRowsToHubDbTable(accountId, tableId, rows = []) {
|
|
|
42
44
|
if (rowsToUpdate.length > 0) {
|
|
43
45
|
await (0, hubdb_1.createRows)(accountId, tableId, rowsToUpdate);
|
|
44
46
|
}
|
|
45
|
-
const { rowCount } = await (0, hubdb_1.publishTable)(accountId, tableId);
|
|
47
|
+
const { data: { rowCount }, } = await (0, hubdb_1.publishTable)(accountId, tableId);
|
|
46
48
|
return {
|
|
47
49
|
tableId,
|
|
48
50
|
rowCount,
|
|
@@ -53,7 +55,7 @@ async function createHubDbTable(accountId, src) {
|
|
|
53
55
|
validateJsonFile(src);
|
|
54
56
|
const table = fs_extra_1.default.readJsonSync(src);
|
|
55
57
|
const { rows, ...schema } = table;
|
|
56
|
-
const { id } = await (0, hubdb_1.createTable)(accountId, schema);
|
|
58
|
+
const { data: { id }, } = await (0, hubdb_1.createTable)(accountId, schema);
|
|
57
59
|
return addRowsToHubDbTable(accountId, id, rows);
|
|
58
60
|
}
|
|
59
61
|
exports.createHubDbTable = createHubDbTable;
|
|
@@ -96,15 +98,15 @@ async function fetchAllRows(accountId, tableId) {
|
|
|
96
98
|
let rows = [];
|
|
97
99
|
let after = null;
|
|
98
100
|
do {
|
|
99
|
-
const
|
|
100
|
-
const { paging, results } =
|
|
101
|
+
const axiosResponse = await (0, hubdb_1.fetchRows)(accountId, tableId, after ? { after } : undefined);
|
|
102
|
+
const { paging, results } = axiosResponse.data;
|
|
101
103
|
rows = rows.concat(results);
|
|
102
104
|
after = paging && paging.next ? paging.next.after : null;
|
|
103
105
|
} while (after !== null);
|
|
104
106
|
return rows;
|
|
105
107
|
}
|
|
106
108
|
async function downloadHubDbTable(accountId, tableId, dest) {
|
|
107
|
-
const table = await (0, hubdb_1.fetchTable)(accountId, tableId);
|
|
109
|
+
const { data: table } = await (0, hubdb_1.fetchTable)(accountId, tableId);
|
|
108
110
|
dest = path_1.default.resolve((0, path_2.getCwd)(), dest || `${table.name}.hubdb.json`);
|
|
109
111
|
if (fs_extra_1.default.pathExistsSync(dest)) {
|
|
110
112
|
validateJsonFile(dest);
|
package/lib/notify.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.triggerNotify = void 0;
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const moment_1 = __importDefault(require("moment"));
|
|
9
9
|
const debounce_1 = __importDefault(require("debounce"));
|
|
10
|
-
const
|
|
10
|
+
const lang_1 = require("../utils/lang");
|
|
11
11
|
const i18nKey = 'utils.notify';
|
|
12
12
|
const notifyQueue = [];
|
|
13
13
|
const notifyPromises = [];
|
|
@@ -37,7 +37,7 @@ function notifyFilePath(filePathToNotify, outputToWrite) {
|
|
|
37
37
|
fs_1.default.appendFileSync(filePathToNotify, outputToWrite);
|
|
38
38
|
}
|
|
39
39
|
catch (e) {
|
|
40
|
-
(0,
|
|
40
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.filePath`, { filePath: filePathToNotify }), { cause: e });
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
package/lib/oauth.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import OAuth2Manager from '../models/OAuth2Manager';
|
|
1
|
+
import { OAuth2Manager } from '../models/OAuth2Manager';
|
|
2
2
|
import { FlatAccountFields } from '../types/Accounts';
|
|
3
3
|
export declare function getOauthManager(accountId: number, accountConfig: FlatAccountFields): OAuth2Manager | undefined;
|
|
4
4
|
export declare function addOauthToAccountConfig(oauth: OAuth2Manager): void;
|
package/lib/oauth.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.addOauthToAccountConfig = exports.getOauthManager = void 0;
|
|
7
|
-
const OAuth2Manager_1 =
|
|
4
|
+
const OAuth2Manager_1 = require("../models/OAuth2Manager");
|
|
8
5
|
const auth_1 = require("../constants/auth");
|
|
9
|
-
const standardErrors_1 = require("../errors/standardErrors");
|
|
10
6
|
const logger_1 = require("./logger");
|
|
11
7
|
const getAccountIdentifier_1 = require("../utils/getAccountIdentifier");
|
|
12
8
|
const config_1 = require("../config");
|
|
@@ -21,23 +17,18 @@ function writeOauthTokenInfo(accountConfig) {
|
|
|
21
17
|
}
|
|
22
18
|
function getOauthManager(accountId, accountConfig) {
|
|
23
19
|
if (!oauthManagers.has(accountId)) {
|
|
24
|
-
oauthManagers.set(accountId, OAuth2Manager_1.
|
|
20
|
+
oauthManagers.set(accountId, OAuth2Manager_1.OAuth2Manager.fromConfig(accountConfig, () => writeOauthTokenInfo(accountConfig)));
|
|
25
21
|
}
|
|
26
22
|
return oauthManagers.get(accountId);
|
|
27
23
|
}
|
|
28
24
|
exports.getOauthManager = getOauthManager;
|
|
29
25
|
function addOauthToAccountConfig(oauth) {
|
|
30
26
|
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.addOauthToAccountConfig.init`));
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.addOauthToAccountConfig.success`));
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
(0, standardErrors_1.throwError)(err);
|
|
41
|
-
}
|
|
27
|
+
(0, config_1.updateAccountConfig)({
|
|
28
|
+
...oauth.account,
|
|
29
|
+
authType: auth_1.AUTH_METHODS.oauth.value,
|
|
30
|
+
});
|
|
31
|
+
(0, config_1.writeConfig)();
|
|
32
|
+
logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.addOauthToAccountConfig.success`));
|
|
42
33
|
}
|
|
43
34
|
exports.addOauthToAccountConfig = addOauthToAccountConfig;
|
package/lib/personalAccessKey.js
CHANGED
|
@@ -7,33 +7,22 @@ exports.updateConfigWithAccessToken = exports.scopesOnAccessToken = exports.enab
|
|
|
7
7
|
const moment_1 = __importDefault(require("moment"));
|
|
8
8
|
const environments_1 = require("../constants/environments");
|
|
9
9
|
const auth_1 = require("../constants/auth");
|
|
10
|
-
const standardErrors_1 = require("../errors/standardErrors");
|
|
11
10
|
const localDevAuth_1 = require("../api/localDevAuth");
|
|
12
11
|
const sandboxHubs_1 = require("../api/sandboxHubs");
|
|
13
12
|
const config_1 = require("../config");
|
|
14
13
|
const config_2 = require("../constants/config");
|
|
15
14
|
const developerTestAccounts_1 = require("../api/developerTestAccounts");
|
|
16
15
|
const logger_1 = require("./logger");
|
|
17
|
-
const
|
|
16
|
+
const lang_1 = require("../utils/lang");
|
|
17
|
+
const errors_1 = require("../errors");
|
|
18
18
|
const i18nKey = 'lib.personalAccessKey';
|
|
19
19
|
const refreshRequests = new Map();
|
|
20
20
|
function getRefreshKey(personalAccessKey, expiration) {
|
|
21
21
|
return `${personalAccessKey}-${expiration || 'fresh'}`;
|
|
22
22
|
}
|
|
23
23
|
async function getAccessToken(personalAccessKey, env = environments_1.ENVIRONMENTS.PROD, accountId) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
response = await (0, localDevAuth_1.fetchAccessToken)(personalAccessKey, env, accountId);
|
|
27
|
-
}
|
|
28
|
-
catch (e) {
|
|
29
|
-
const error = e;
|
|
30
|
-
if (error.response) {
|
|
31
|
-
(0, standardErrors_1.throwAuthErrorWithMessage)(`${i18nKey}.errors.invalidPersonalAccessKey`, { errorMessage: error.response.data.message || '' }, error);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
(0, standardErrors_1.throwError)(e);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
24
|
+
const axiosResponse = await (0, localDevAuth_1.fetchAccessToken)(personalAccessKey, env, accountId);
|
|
25
|
+
const response = axiosResponse.data;
|
|
37
26
|
return {
|
|
38
27
|
portalId: response.hubId,
|
|
39
28
|
accessToken: response.oauthAccessToken,
|
|
@@ -86,7 +75,7 @@ async function getNewAccessToken(accountId, personalAccessKey, expiresAt, env) {
|
|
|
86
75
|
async function getNewAccessTokenByAccountId(accountId) {
|
|
87
76
|
const account = (0, config_1.getAccountConfig)(accountId);
|
|
88
77
|
if (!account) {
|
|
89
|
-
(0,
|
|
78
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.accountNotFound`, { accountId }));
|
|
90
79
|
}
|
|
91
80
|
const { auth, personalAccessKey, env } = account;
|
|
92
81
|
const accessTokenResponse = await getNewAccessToken(accountId, personalAccessKey, auth?.tokenInfo?.expiresAt, env);
|
|
@@ -95,7 +84,7 @@ async function getNewAccessTokenByAccountId(accountId) {
|
|
|
95
84
|
async function accessTokenForPersonalAccessKey(accountId, forceRefresh = false) {
|
|
96
85
|
const account = (0, config_1.getAccountConfig)(accountId);
|
|
97
86
|
if (!account) {
|
|
98
|
-
(0,
|
|
87
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.accountNotFound`, { accountId }));
|
|
99
88
|
}
|
|
100
89
|
const { auth, personalAccessKey, env } = account;
|
|
101
90
|
const authTokenInfo = auth && auth.tokenInfo;
|
|
@@ -124,7 +113,7 @@ async function updateConfigWithAccessToken(token, personalAccessKey, env, name,
|
|
|
124
113
|
try {
|
|
125
114
|
if (accountType === config_2.HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX ||
|
|
126
115
|
accountType === config_2.HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX) {
|
|
127
|
-
const sandboxDataResponse = await (0, sandboxHubs_1.fetchSandboxHubData)(accessToken, portalId, accountEnv);
|
|
116
|
+
const { data: sandboxDataResponse } = await (0, sandboxHubs_1.fetchSandboxHubData)(accessToken, portalId, accountEnv);
|
|
128
117
|
if (sandboxDataResponse.parentHubId) {
|
|
129
118
|
parentAccountId = sandboxDataResponse.parentHubId;
|
|
130
119
|
}
|
|
@@ -132,11 +121,14 @@ async function updateConfigWithAccessToken(token, personalAccessKey, env, name,
|
|
|
132
121
|
}
|
|
133
122
|
catch (err) {
|
|
134
123
|
// Log error but do not throw
|
|
135
|
-
|
|
124
|
+
if ((0, errors_1.isHubSpotHttpError)(err)) {
|
|
125
|
+
logger_1.logger.debug(err.message);
|
|
126
|
+
}
|
|
127
|
+
logger_1.logger.debug(err);
|
|
136
128
|
}
|
|
137
129
|
try {
|
|
138
130
|
if (accountType === config_2.HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST) {
|
|
139
|
-
const developerTestAccountResponse = await (0, developerTestAccounts_1.fetchDeveloperTestAccountData)(accessToken, portalId, accountEnv);
|
|
131
|
+
const { data: developerTestAccountResponse } = await (0, developerTestAccounts_1.fetchDeveloperTestAccountData)(accessToken, portalId, accountEnv);
|
|
140
132
|
if (developerTestAccountResponse) {
|
|
141
133
|
parentAccountId = developerTestAccountResponse.parentPortalId;
|
|
142
134
|
}
|
|
@@ -144,7 +136,10 @@ async function updateConfigWithAccessToken(token, personalAccessKey, env, name,
|
|
|
144
136
|
}
|
|
145
137
|
catch (err) {
|
|
146
138
|
// Log error but do not throw
|
|
147
|
-
|
|
139
|
+
if ((0, errors_1.isHubSpotHttpError)(err)) {
|
|
140
|
+
logger_1.logger.debug(err.message);
|
|
141
|
+
}
|
|
142
|
+
logger_1.logger.debug(err);
|
|
148
143
|
}
|
|
149
144
|
const updatedConfig = (0, config_1.updateAccountConfig)({
|
|
150
145
|
accountId: portalId,
|
package/lib/portManager.js
CHANGED
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.portManagerHasActiveServers = exports.deleteServerInstance = exports.requestPorts = exports.stopPortManagerServer = exports.startPortManagerServer = exports.BASE_URL = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
|
-
const PortManagerServer_1 =
|
|
8
|
+
const PortManagerServer_1 = require("../utils/PortManagerServer");
|
|
9
9
|
const detectPort_1 = require("../utils/detectPort");
|
|
10
10
|
const ports_1 = require("../constants/ports");
|
|
11
11
|
exports.BASE_URL = `http://localhost:${ports_1.PORT_MANAGER_SERVER_PORT}`;
|
|
@@ -16,7 +16,7 @@ async function isPortManagerServerRunning() {
|
|
|
16
16
|
async function startPortManagerServer() {
|
|
17
17
|
const isRunning = await isPortManagerServerRunning();
|
|
18
18
|
if (!isRunning) {
|
|
19
|
-
await PortManagerServer_1.
|
|
19
|
+
await PortManagerServer_1.PortManagerServer.init();
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
exports.startPortManagerServer = startPortManagerServer;
|
package/lib/trackUsage.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.trackUsage = void 0;
|
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const getAxiosConfig_1 = require("../http/getAxiosConfig");
|
|
9
9
|
const logger_1 = require("./logger");
|
|
10
|
-
const http_1 =
|
|
10
|
+
const http_1 = require("../http");
|
|
11
11
|
const config_1 = require("../config");
|
|
12
12
|
const fileMapper_1 = require("../api/fileMapper");
|
|
13
13
|
const lang_1 = require("../utils/lang");
|
|
@@ -38,11 +38,17 @@ async function trackUsage(eventName, eventClass, meta = {}, accountId) {
|
|
|
38
38
|
const accountConfig = accountId && (0, config_1.getAccountConfig)(accountId);
|
|
39
39
|
if (accountConfig && accountConfig.authType === 'personalaccesskey') {
|
|
40
40
|
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.sendingEventAuthenticated`));
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
try {
|
|
42
|
+
await http_1.http.post(accountId, {
|
|
43
|
+
url: `${path}/authenticated`,
|
|
44
|
+
data: usageEvent,
|
|
45
|
+
resolveWithFullResponse: true,
|
|
46
|
+
});
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.retryingEventUnauthenticated`));
|
|
51
|
+
}
|
|
46
52
|
}
|
|
47
53
|
const env = (0, config_1.getEnv)(accountId);
|
|
48
54
|
const axiosConfig = (0, getAxiosConfig_1.getAxiosConfig)({
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FileSystemError = void 0;
|
|
4
|
+
const lang_1 = require("../utils/lang");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const i18nKey = 'errors.fileSystemErrors';
|
|
7
|
+
class FileSystemError extends Error {
|
|
8
|
+
context;
|
|
9
|
+
constructor(options, context) {
|
|
10
|
+
super('', options);
|
|
11
|
+
this.name = 'FileSystemError';
|
|
12
|
+
this.context = context;
|
|
13
|
+
if (context) {
|
|
14
|
+
let fileAction = '';
|
|
15
|
+
if (context.operation === 'read') {
|
|
16
|
+
fileAction = (0, lang_1.i18n)(`${i18nKey}.readAction`);
|
|
17
|
+
}
|
|
18
|
+
else if (context.operation === 'write') {
|
|
19
|
+
fileAction = (0, lang_1.i18n)(`${i18nKey}.writeAction`);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
fileAction = (0, lang_1.i18n)(`${i18nKey}.otherAction`);
|
|
23
|
+
}
|
|
24
|
+
const filepath = context.filepath
|
|
25
|
+
? `"${context.filepath}"`
|
|
26
|
+
: (0, lang_1.i18n)(`${i18nKey}.unknownFilepath`);
|
|
27
|
+
const messages = [
|
|
28
|
+
(0, lang_1.i18n)(`${i18nKey}.baseMessage`, { fileAction, filepath }),
|
|
29
|
+
];
|
|
30
|
+
// Many `fs` errors will be `SystemError`s
|
|
31
|
+
if ((0, errors_1.isSystemError)(options?.cause)) {
|
|
32
|
+
messages.push((0, lang_1.i18n)(`${i18nKey}.baseMessage`, {
|
|
33
|
+
errorMessage: options?.cause?.message || '',
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
this.message = messages.join(' ');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
toString() {
|
|
40
|
+
let baseString = `${this.name}: ${this.message}`;
|
|
41
|
+
if (this.context) {
|
|
42
|
+
baseString = `${baseString} context: ${this.context}`;
|
|
43
|
+
}
|
|
44
|
+
return baseString;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.FileSystemError = FileSystemError;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { HubSpotHttpErrorContext } from '../types/Error';
|
|
2
|
+
export declare class HubSpotHttpError<T = any> extends Error {
|
|
3
|
+
status?: number;
|
|
4
|
+
code?: string;
|
|
5
|
+
statusText?: string;
|
|
6
|
+
data?: T;
|
|
7
|
+
headers?: {
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
};
|
|
10
|
+
method: string | undefined;
|
|
11
|
+
context: HubSpotHttpErrorContext | undefined;
|
|
12
|
+
derivedContext: HubSpotHttpErrorContext | undefined;
|
|
13
|
+
validationErrors: string[] | undefined;
|
|
14
|
+
detailedMessage?: string;
|
|
15
|
+
private divider;
|
|
16
|
+
cause: ErrorOptions['cause'];
|
|
17
|
+
constructor(message?: string, options?: ErrorOptions, context?: HubSpotHttpErrorContext);
|
|
18
|
+
updateContext(context: Partial<HubSpotHttpErrorContext>): void;
|
|
19
|
+
toString(): string;
|
|
20
|
+
formattedValidationErrors(): string;
|
|
21
|
+
private extractDerivedContext;
|
|
22
|
+
private parseValidationErrors;
|
|
23
|
+
private joinErrorMessages;
|
|
24
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HubSpotHttpError = void 0;
|
|
4
|
+
const axios_1 = require("axios");
|
|
5
|
+
const api_1 = require("../constants/api");
|
|
6
|
+
const lang_1 = require("../utils/lang");
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
+
class HubSpotHttpError extends Error {
|
|
9
|
+
status;
|
|
10
|
+
code;
|
|
11
|
+
statusText;
|
|
12
|
+
data;
|
|
13
|
+
headers;
|
|
14
|
+
method;
|
|
15
|
+
context;
|
|
16
|
+
derivedContext;
|
|
17
|
+
validationErrors;
|
|
18
|
+
detailedMessage;
|
|
19
|
+
divider = `\n- `;
|
|
20
|
+
cause;
|
|
21
|
+
constructor(message, options, context) {
|
|
22
|
+
super(message, options);
|
|
23
|
+
this.name = 'HubSpotHttpError';
|
|
24
|
+
this.context = context;
|
|
25
|
+
this.cause = options?.cause;
|
|
26
|
+
if (options && (0, axios_1.isAxiosError)(options.cause)) {
|
|
27
|
+
this.extractDerivedContext(options.cause);
|
|
28
|
+
const { response, config, code } = options.cause;
|
|
29
|
+
this.message = this.joinErrorMessages(options.cause, {
|
|
30
|
+
accountId: this.context?.accountId || this.derivedContext?.accountId,
|
|
31
|
+
});
|
|
32
|
+
this.detailedMessage = this.joinErrorMessages(options.cause, this.context);
|
|
33
|
+
this.code = code;
|
|
34
|
+
this.method = config?.method;
|
|
35
|
+
// Pull the request fields to the top level
|
|
36
|
+
if (response) {
|
|
37
|
+
this.status = response.status;
|
|
38
|
+
this.statusText = response.statusText;
|
|
39
|
+
this.data = response.data;
|
|
40
|
+
this.headers = response.headers;
|
|
41
|
+
this.parseValidationErrors(response.data);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (options && options.cause instanceof Error) {
|
|
45
|
+
const messages = options.cause.name !== 'Error' ? [`${options.cause.name}:`] : [];
|
|
46
|
+
if (options.cause.message) {
|
|
47
|
+
messages.push(options.cause.message);
|
|
48
|
+
}
|
|
49
|
+
if ('reason' in options.cause && options.cause.reason) {
|
|
50
|
+
messages.push(`${options.cause.reason}`);
|
|
51
|
+
}
|
|
52
|
+
this.message = messages.join(' ');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
updateContext(context) {
|
|
56
|
+
this.context = { ...this.context, ...context };
|
|
57
|
+
// Update the error messages when the context is updated
|
|
58
|
+
if ((0, axios_1.isAxiosError)(this.cause)) {
|
|
59
|
+
this.message = this.joinErrorMessages(this.cause, this.context);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
toString() {
|
|
63
|
+
const messages = [
|
|
64
|
+
`${this.name}: ${this.divider}message: ${this.detailedMessage}`,
|
|
65
|
+
];
|
|
66
|
+
['status', 'statusText', 'method', 'code'].forEach(field => {
|
|
67
|
+
if (Object.hasOwn(this, field)) {
|
|
68
|
+
// @ts-expect-error this[field] exists, so we know it is a property of this
|
|
69
|
+
messages.push(`${field}: ${this[field]}`);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
if (this.validationErrors && this.validationErrors.length > 0) {
|
|
73
|
+
messages.push(`errors: ${this.formattedValidationErrors()}`);
|
|
74
|
+
}
|
|
75
|
+
if (this.context) {
|
|
76
|
+
messages.push(`context: ${JSON.stringify(this.context, undefined, 2)}`);
|
|
77
|
+
}
|
|
78
|
+
if (this.derivedContext) {
|
|
79
|
+
messages.push(`derivedContext: ${JSON.stringify(this.derivedContext, undefined, 2)}`);
|
|
80
|
+
}
|
|
81
|
+
return messages.join(this.divider);
|
|
82
|
+
}
|
|
83
|
+
formattedValidationErrors() {
|
|
84
|
+
if (!this.validationErrors || this.validationErrors?.length === 0) {
|
|
85
|
+
return '';
|
|
86
|
+
}
|
|
87
|
+
return this.validationErrors?.join(this.divider);
|
|
88
|
+
}
|
|
89
|
+
extractDerivedContext(cause) {
|
|
90
|
+
const generatedContext = {};
|
|
91
|
+
if (!cause) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
generatedContext.accountId = cause.config?.params?.portalId;
|
|
95
|
+
generatedContext.payload = JSON.stringify(cause.config?.data);
|
|
96
|
+
// This will just be the url path
|
|
97
|
+
generatedContext.request = cause.config?.url;
|
|
98
|
+
// Allow the provided context to override the generated context
|
|
99
|
+
this.derivedContext = { ...this.derivedContext, ...generatedContext };
|
|
100
|
+
}
|
|
101
|
+
parseValidationErrors(responseData = { errors: [], message: '' }) {
|
|
102
|
+
if (!responseData) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const errorMessages = [];
|
|
106
|
+
const { errors, message } = responseData;
|
|
107
|
+
if (message) {
|
|
108
|
+
errorMessages.push(message);
|
|
109
|
+
}
|
|
110
|
+
if (errors) {
|
|
111
|
+
const specificErrors = errors.map(error => {
|
|
112
|
+
let errorMessage = error.message;
|
|
113
|
+
if (error.context?.requiredScopes) {
|
|
114
|
+
// Sometimes the scopes come back with duplicates
|
|
115
|
+
const scopes = new Set(error.context.requiredScopes);
|
|
116
|
+
scopes.forEach(item => {
|
|
117
|
+
errorMessage = `${errorMessage}\n - ${item}`;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
else if (error.errorTokens && error.errorTokens.line) {
|
|
121
|
+
errorMessage = `line ${error.errorTokens.line}: ${errorMessage}`;
|
|
122
|
+
}
|
|
123
|
+
return errorMessage;
|
|
124
|
+
});
|
|
125
|
+
errorMessages.push(...specificErrors);
|
|
126
|
+
}
|
|
127
|
+
this.validationErrors = errorMessages;
|
|
128
|
+
}
|
|
129
|
+
joinErrorMessages(error, context = {}) {
|
|
130
|
+
const i18nKey = 'errors.apiErrors';
|
|
131
|
+
const status = error.response?.status;
|
|
132
|
+
const method = error.config?.method;
|
|
133
|
+
let messageDetail;
|
|
134
|
+
if (context.accountId) {
|
|
135
|
+
const action = (method && api_1.HTTP_METHOD_VERBS[method]) || api_1.HTTP_METHOD_VERBS.get;
|
|
136
|
+
const preposition = (method && api_1.HTTP_METHOD_PREPOSITIONS[method]) ||
|
|
137
|
+
api_1.HTTP_METHOD_PREPOSITIONS.get;
|
|
138
|
+
const requestName = context.request
|
|
139
|
+
? `${action} ${preposition} '${context.request}'`
|
|
140
|
+
: action;
|
|
141
|
+
messageDetail = (0, lang_1.i18n)(`${i18nKey}.messageDetail`, {
|
|
142
|
+
accountId: context.accountId,
|
|
143
|
+
requestName,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
messageDetail = (0, lang_1.i18n)(`${i18nKey}.genericMessageDetail`);
|
|
148
|
+
}
|
|
149
|
+
const errorMessage = [];
|
|
150
|
+
if ((method === 'put' || method === 'post') && context.payload) {
|
|
151
|
+
errorMessage.push((0, lang_1.i18n)(`${i18nKey}.unableToUpload`, { payload: context.payload }));
|
|
152
|
+
}
|
|
153
|
+
switch (status) {
|
|
154
|
+
case 400:
|
|
155
|
+
errorMessage.push((0, lang_1.i18n)(`${i18nKey}.codes.400`, { messageDetail }));
|
|
156
|
+
break;
|
|
157
|
+
case 401:
|
|
158
|
+
errorMessage.push((0, lang_1.i18n)(`${i18nKey}.codes.401`, { messageDetail }));
|
|
159
|
+
break;
|
|
160
|
+
case 403:
|
|
161
|
+
break;
|
|
162
|
+
case 404:
|
|
163
|
+
errorMessage.push((0, lang_1.i18n)(`${i18nKey}.codes.404`, { messageDetail }));
|
|
164
|
+
break;
|
|
165
|
+
case 429:
|
|
166
|
+
errorMessage.push((0, lang_1.i18n)(`${i18nKey}.codes.429`, { messageDetail }));
|
|
167
|
+
break;
|
|
168
|
+
case 503:
|
|
169
|
+
errorMessage.push((0, lang_1.i18n)(`${i18nKey}.codes.503`, { messageDetail }));
|
|
170
|
+
break;
|
|
171
|
+
default:
|
|
172
|
+
if (status && status >= 500 && status < 600) {
|
|
173
|
+
errorMessage.push((0, lang_1.i18n)(`${i18nKey}.codes.500Generic`, { messageDetail }));
|
|
174
|
+
}
|
|
175
|
+
else if (status && status >= 400 && status < 500) {
|
|
176
|
+
errorMessage.push((0, lang_1.i18n)(`${i18nKey}.codes.400Generic`, { messageDetail }));
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
errorMessage.push((0, lang_1.i18n)(`${i18nKey}.codes.generic`, { messageDetail }));
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
if (error?.response?.data) {
|
|
184
|
+
const { message, errors } = error.response.data;
|
|
185
|
+
if (message) {
|
|
186
|
+
errorMessage.push(message);
|
|
187
|
+
}
|
|
188
|
+
(errors || []).forEach(err => {
|
|
189
|
+
if (err.message) {
|
|
190
|
+
errorMessage.push(`${this.divider}${err.message}`);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
return errorMessage.join(' ');
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.HubSpotHttpError = HubSpotHttpError;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FlatAccountFields, OAuth2ManagerAccountConfig, WriteTokenInfoFunction, RefreshTokenResponse, ExchangeProof } from '../types/Accounts';
|
|
2
|
-
declare class OAuth2Manager {
|
|
2
|
+
export declare class OAuth2Manager {
|
|
3
3
|
account: OAuth2ManagerAccountConfig;
|
|
4
4
|
writeTokenInfo?: WriteTokenInfoFunction;
|
|
5
5
|
refreshTokenRequest: Promise<RefreshTokenResponse> | null;
|
|
@@ -10,4 +10,3 @@ declare class OAuth2Manager {
|
|
|
10
10
|
refreshAccessToken(): Promise<void>;
|
|
11
11
|
static fromConfig(accountConfig: FlatAccountFields, writeTokenInfo: WriteTokenInfoFunction): OAuth2Manager;
|
|
12
12
|
}
|
|
13
|
-
export default OAuth2Manager;
|
package/models/OAuth2Manager.js
CHANGED
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OAuth2Manager = void 0;
|
|
6
7
|
const axios_1 = __importDefault(require("axios"));
|
|
7
8
|
const moment_1 = __importDefault(require("moment"));
|
|
8
9
|
const urls_1 = require("../lib/urls");
|
|
@@ -10,7 +11,6 @@ const environment_1 = require("../lib/environment");
|
|
|
10
11
|
const logger_1 = require("../lib/logger");
|
|
11
12
|
const getAccountIdentifier_1 = require("../utils/getAccountIdentifier");
|
|
12
13
|
const auth_1 = require("../constants/auth");
|
|
13
|
-
const standardErrors_1 = require("../errors/standardErrors");
|
|
14
14
|
const lang_1 = require("../utils/lang");
|
|
15
15
|
const i18nKey = 'models.OAuth2Manager';
|
|
16
16
|
class OAuth2Manager {
|
|
@@ -27,9 +27,9 @@ class OAuth2Manager {
|
|
|
27
27
|
}
|
|
28
28
|
async accessToken() {
|
|
29
29
|
if (!this.account.tokenInfo?.refreshToken) {
|
|
30
|
-
(0,
|
|
30
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.missingRefreshToken`, {
|
|
31
31
|
accountId: (0, getAccountIdentifier_1.getAccountIdentifier)(this.account),
|
|
32
|
-
});
|
|
32
|
+
}));
|
|
33
33
|
}
|
|
34
34
|
if (!this.account.tokenInfo?.accessToken ||
|
|
35
35
|
(0, moment_1.default)()
|
|
@@ -68,36 +68,21 @@ class OAuth2Manager {
|
|
|
68
68
|
}));
|
|
69
69
|
this.writeTokenInfo(this.account.tokenInfo);
|
|
70
70
|
}
|
|
71
|
-
this.refreshTokenRequest = null;
|
|
72
71
|
}
|
|
73
|
-
|
|
72
|
+
finally {
|
|
74
73
|
this.refreshTokenRequest = null;
|
|
75
|
-
(0, standardErrors_1.throwError)(e);
|
|
76
74
|
}
|
|
77
75
|
}
|
|
78
76
|
async exchangeForTokens(exchangeProof) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
await this.refreshTokenRequest;
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
await this.fetchAccessToken(exchangeProof);
|
|
89
|
-
}
|
|
77
|
+
if (this.refreshTokenRequest) {
|
|
78
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.refreshingAccessToken`, {
|
|
79
|
+
accountId: (0, getAccountIdentifier_1.getAccountIdentifier)(this.account),
|
|
80
|
+
clientId: this.account.clientId || '',
|
|
81
|
+
}));
|
|
82
|
+
await this.refreshTokenRequest;
|
|
90
83
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (error.response) {
|
|
94
|
-
(0, standardErrors_1.throwAuthErrorWithMessage)(`${i18nKey}.errors.auth`, {
|
|
95
|
-
token: error.response.data.message || '',
|
|
96
|
-
}, error);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
(0, standardErrors_1.throwError)(error);
|
|
100
|
-
}
|
|
84
|
+
else {
|
|
85
|
+
await this.fetchAccessToken(exchangeProof);
|
|
101
86
|
}
|
|
102
87
|
}
|
|
103
88
|
async refreshAccessToken() {
|
|
@@ -117,4 +102,4 @@ class OAuth2Manager {
|
|
|
117
102
|
}, writeTokenInfo);
|
|
118
103
|
}
|
|
119
104
|
}
|
|
120
|
-
exports.
|
|
105
|
+
exports.OAuth2Manager = OAuth2Manager;
|