@hubspot/local-dev-lib 0.5.0-experimental.9 → 0.6.1-experimental.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/fireAlarm.d.ts +1 -0
- package/api/fireAlarm.js +3 -3
- package/api/projects.d.ts +6 -1
- package/api/projects.js +26 -1
- package/config/index.d.ts +5 -3
- package/config/index.js +48 -29
- package/config/migrate.d.ts +1 -0
- package/config/migrate.js +13 -5
- package/config/utils.d.ts +5 -54
- package/config/utils.js +59 -38
- package/errors/index.d.ts +2 -2
- package/errors/index.js +2 -2
- package/http/getAxiosConfig.d.ts +2 -0
- package/http/getAxiosConfig.js +74 -5
- package/http/index.js +11 -2
- package/lang/en.json +13 -13
- package/lib/personalAccessKey.js +3 -3
- package/lib/portManager.d.ts +2 -1
- package/lib/portManager.js +6 -1
- package/models/FileSystemError.d.ts +1 -0
- package/models/FileSystemError.js +3 -2
- package/models/HubSpotHttpError.d.ts +2 -1
- package/models/HubSpotHttpError.js +37 -17
- package/package.json +6 -4
- package/types/Config.d.ts +4 -0
- package/types/Deploy.d.ts +12 -7
- package/utils/git.js +2 -1
package/api/fireAlarm.d.ts
CHANGED
package/api/fireAlarm.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fetchFireAlarms = void 0;
|
|
3
|
+
exports.fetchFireAlarms = exports.FIREALARM_API_AUTH_PATH = void 0;
|
|
4
4
|
const http_1 = require("../http");
|
|
5
|
-
|
|
5
|
+
exports.FIREALARM_API_AUTH_PATH = 'firealarm/v4/alarm';
|
|
6
6
|
function fetchFireAlarms(accountId) {
|
|
7
7
|
return http_1.http.get(accountId, {
|
|
8
|
-
url: `${FIREALARM_API_AUTH_PATH}/hubspot-cli/${accountId}`,
|
|
8
|
+
url: `${exports.FIREALARM_API_AUTH_PATH}/hubspot-cli/${accountId}`,
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
exports.fetchFireAlarms = fetchFireAlarms;
|
package/api/projects.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { HubSpotPromise, QueryParams } from '../types/Http';
|
|
|
4
4
|
import { Project, FetchProjectResponse, UploadProjectResponse, ProjectSettings, FetchPlatformVersionResponse, WarnLogsResponse, UploadIRResponse } from '../types/Project';
|
|
5
5
|
import { Build, FetchProjectBuildsResponse } from '../types/Build';
|
|
6
6
|
import { ComponentStructureResponse, ProjectComponentsMetadata } from '../types/ComponentStructure';
|
|
7
|
-
import { Deploy, ProjectDeployResponse } from '../types/Deploy';
|
|
7
|
+
import { Deploy, ProjectDeployResponse, ProjectDeployResponseV1 } from '../types/Deploy';
|
|
8
8
|
import { MigrateAppResponse, CloneAppResponse, PollAppResponse } from '../types/Migration';
|
|
9
9
|
export declare function fetchProjects(accountId: number): HubSpotPromise<FetchProjectResponse>;
|
|
10
10
|
export declare function createProject(accountId: number, name: string): HubSpotPromise<Project>;
|
|
@@ -17,7 +17,12 @@ export declare function fetchPlatformVersions(accountId: number): HubSpotPromise
|
|
|
17
17
|
export declare function fetchProjectBuilds(accountId: number, projectName: string, params?: QueryParams): HubSpotPromise<FetchProjectBuildsResponse>;
|
|
18
18
|
export declare function getBuildStatus(accountId: number, projectName: string, buildId: number): HubSpotPromise<Build>;
|
|
19
19
|
export declare function getBuildStructure(accountId: number, projectName: string, buildId: number): HubSpotPromise<ComponentStructureResponse>;
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Use the separate deployProjectV1 and deployProjectV2
|
|
22
|
+
*/
|
|
20
23
|
export declare function deployProject(accountId: number, projectName: string, buildId: number, useNewDeployApi?: boolean, force?: boolean): HubSpotPromise<ProjectDeployResponse>;
|
|
24
|
+
export declare function deployProjectV1(accountId: number, projectName: string, buildId: number, force?: boolean): HubSpotPromise<ProjectDeployResponseV1>;
|
|
25
|
+
export declare function deployProjectV2(accountId: number, projectName: string, buildId: number, force?: boolean): HubSpotPromise<ProjectDeployResponse>;
|
|
21
26
|
export declare function getDeployStatus(accountId: number, projectName: string, deployId: number): HubSpotPromise<Deploy>;
|
|
22
27
|
export declare function getDeployStructure(accountId: number, projectName: string, deployId: number): HubSpotPromise<ComponentStructureResponse>;
|
|
23
28
|
export declare function fetchProjectSettings(accountId: number, projectName: string): HubSpotPromise<ProjectSettings>;
|
package/api/projects.js
CHANGED
|
@@ -3,7 +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.downloadClonedProject = exports.checkCloneStatus = exports.cloneApp = exports.checkMigrationStatus = exports.migrateApp = exports.fetchDeployWarnLogs = exports.fetchBuildWarnLogs = exports.cancelStagedBuild = exports.deleteFileFromBuild = exports.uploadFileToBuild = exports.queueBuild = exports.provisionBuild = exports.fetchProjectSettings = exports.getDeployStructure = exports.getDeployStatus = exports.deployProject = exports.getBuildStructure = exports.getBuildStatus = exports.fetchProjectBuilds = exports.fetchPlatformVersions = exports.deleteProject = exports.downloadProject = exports.fetchProjectComponentsMetadata = exports.fetchProject = exports.uploadProject = exports.createProject = exports.fetchProjects = void 0;
|
|
6
|
+
exports.downloadClonedProject = exports.checkCloneStatus = exports.cloneApp = exports.checkMigrationStatus = exports.migrateApp = exports.fetchDeployWarnLogs = exports.fetchBuildWarnLogs = exports.cancelStagedBuild = exports.deleteFileFromBuild = exports.uploadFileToBuild = exports.queueBuild = exports.provisionBuild = exports.fetchProjectSettings = exports.getDeployStructure = exports.getDeployStatus = exports.deployProjectV2 = exports.deployProjectV1 = exports.deployProject = exports.getBuildStructure = exports.getBuildStatus = exports.fetchProjectBuilds = exports.fetchPlatformVersions = exports.deleteProject = exports.downloadProject = exports.fetchProjectComponentsMetadata = exports.fetchProject = exports.uploadProject = exports.createProject = exports.fetchProjects = void 0;
|
|
7
7
|
const http_1 = require("../http");
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const PROJECTS_API_PATH = 'dfs/v1/projects';
|
|
@@ -116,6 +116,9 @@ function getBuildStructure(accountId, projectName, buildId) {
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
exports.getBuildStructure = getBuildStructure;
|
|
119
|
+
/**
|
|
120
|
+
* @deprecated Use the separate deployProjectV1 and deployProjectV2
|
|
121
|
+
*/
|
|
119
122
|
function deployProject(accountId, projectName, buildId, useNewDeployApi = false, force = false) {
|
|
120
123
|
if (useNewDeployApi) {
|
|
121
124
|
return http_1.http.post(accountId, {
|
|
@@ -137,6 +140,28 @@ function deployProject(accountId, projectName, buildId, useNewDeployApi = false,
|
|
|
137
140
|
});
|
|
138
141
|
}
|
|
139
142
|
exports.deployProject = deployProject;
|
|
143
|
+
function deployProjectV1(accountId, projectName, buildId, force = false) {
|
|
144
|
+
return http_1.http.post(accountId, {
|
|
145
|
+
url: `${PROJECTS_DEPLOY_API_PATH}/deploys/queue/async`,
|
|
146
|
+
data: {
|
|
147
|
+
projectName,
|
|
148
|
+
buildId,
|
|
149
|
+
skipRemovalWarning: force,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
exports.deployProjectV1 = deployProjectV1;
|
|
154
|
+
function deployProjectV2(accountId, projectName, buildId, force = false) {
|
|
155
|
+
return http_1.http.post(accountId, {
|
|
156
|
+
url: `${PROJECTS_DEPLOY_API_PATH_V3}/deploys/queue/async`,
|
|
157
|
+
data: {
|
|
158
|
+
projectName,
|
|
159
|
+
targetBuildId: buildId,
|
|
160
|
+
ignoreWarnings: force,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
exports.deployProjectV2 = deployProjectV2;
|
|
140
165
|
function getDeployStatus(accountId, projectName, deployId) {
|
|
141
166
|
return http_1.http.get(accountId, {
|
|
142
167
|
url: `${PROJECTS_DEPLOY_API_PATH}/deploy-status/projects/${encodeURIComponent(projectName)}/deploys/${deployId}`,
|
package/config/index.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { HubSpotConfigAccount } from '../types/Accounts';
|
|
2
|
-
import { HubSpotConfig, ConfigFlag } from '../types/Config';
|
|
2
|
+
import { HubSpotConfig, ConfigFlag, HubSpotConfigValidationResult } from '../types/Config';
|
|
3
3
|
import { CmsPublishMode } from '../types/Files';
|
|
4
4
|
import { Environment } from '../types/Config';
|
|
5
|
+
export declare function getGlobalConfigFilePath(): string;
|
|
6
|
+
export declare function getLocalConfigFilePathIfExists(cwd?: string): string | null;
|
|
5
7
|
export declare function localConfigFileExists(): boolean;
|
|
6
8
|
export declare function globalConfigFileExists(): boolean;
|
|
7
9
|
export declare function configFileExists(): boolean;
|
|
8
10
|
export declare function getConfigFilePath(): string;
|
|
9
11
|
export declare function getConfig(): HubSpotConfig;
|
|
10
|
-
export declare function
|
|
12
|
+
export declare function validateConfig(): HubSpotConfigValidationResult;
|
|
11
13
|
export declare function createEmptyConfigFile(useGlobalConfig?: boolean): void;
|
|
12
|
-
export declare function
|
|
14
|
+
export declare function deleteConfigFileIfEmpty(): void;
|
|
13
15
|
export declare function getConfigAccountById(accountId: number): HubSpotConfigAccount;
|
|
14
16
|
export declare function getConfigAccountByName(accountName: string): HubSpotConfigAccount;
|
|
15
17
|
export declare function getConfigAccountIfExists(identifier: number | string): HubSpotConfigAccount | undefined;
|
package/config/index.js
CHANGED
|
@@ -3,8 +3,9 @@ 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.removeLocalStateFlag = exports.addLocalStateFlag = exports.hasLocalStateFlag = exports.isConfigFlagEnabled = exports.updateDefaultCmsPublishMode = exports.updateAutoOpenBrowser = exports.updateAllowAutoUpdates = exports.updateAllowUsageTracking = exports.updateHttpTimeout = exports.removeAccountFromConfig = exports.renameConfigAccount = exports.setConfigAccountAsDefault = exports.updateConfigAccount = exports.addConfigAccount = exports.getConfigAccountEnvironment = exports.getAllConfigAccounts = exports.getConfigDefaultAccountIfExists = exports.getConfigDefaultAccount = exports.getConfigAccountIfExists = exports.getConfigAccountByName = exports.getConfigAccountById = exports.
|
|
6
|
+
exports.removeLocalStateFlag = exports.addLocalStateFlag = exports.hasLocalStateFlag = exports.isConfigFlagEnabled = exports.updateDefaultCmsPublishMode = exports.updateAutoOpenBrowser = exports.updateAllowAutoUpdates = exports.updateAllowUsageTracking = exports.updateHttpTimeout = exports.removeAccountFromConfig = exports.renameConfigAccount = exports.setConfigAccountAsDefault = exports.updateConfigAccount = exports.addConfigAccount = exports.getConfigAccountEnvironment = exports.getAllConfigAccounts = exports.getConfigDefaultAccountIfExists = exports.getConfigDefaultAccount = exports.getConfigAccountIfExists = exports.getConfigAccountByName = exports.getConfigAccountById = exports.deleteConfigFileIfEmpty = exports.createEmptyConfigFile = exports.validateConfig = exports.getConfig = exports.getConfigFilePath = exports.configFileExists = exports.globalConfigFileExists = exports.localConfigFileExists = exports.getLocalConfigFilePathIfExists = exports.getGlobalConfigFilePath = void 0;
|
|
7
7
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const findup_sync_1 = __importDefault(require("findup-sync"));
|
|
8
9
|
const config_1 = require("../constants/config");
|
|
9
10
|
const logger_1 = require("../lib/logger");
|
|
10
11
|
const utils_1 = require("./utils");
|
|
@@ -14,12 +15,26 @@ const defaultAccountOverride_1 = require("./defaultAccountOverride");
|
|
|
14
15
|
const environment_1 = require("../lib/environment");
|
|
15
16
|
const HubSpotConfigError_1 = require("../models/HubSpotConfigError");
|
|
16
17
|
const config_2 = require("../constants/config");
|
|
18
|
+
const isDeepEqual_1 = require("../lib/isDeepEqual");
|
|
19
|
+
const path_1 = require("../lib/path");
|
|
20
|
+
const EMPTY_CONFIG = { accounts: [] };
|
|
21
|
+
function getGlobalConfigFilePath() {
|
|
22
|
+
return config_1.GLOBAL_CONFIG_PATH;
|
|
23
|
+
}
|
|
24
|
+
exports.getGlobalConfigFilePath = getGlobalConfigFilePath;
|
|
25
|
+
function getLocalConfigFilePathIfExists(cwd) {
|
|
26
|
+
return (0, findup_sync_1.default)([
|
|
27
|
+
config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
|
|
28
|
+
config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME.replace('.yml', '.yaml'),
|
|
29
|
+
], { cwd: cwd || (0, path_1.getCwd)() });
|
|
30
|
+
}
|
|
31
|
+
exports.getLocalConfigFilePathIfExists = getLocalConfigFilePathIfExists;
|
|
17
32
|
function localConfigFileExists() {
|
|
18
|
-
return Boolean((
|
|
33
|
+
return Boolean(getLocalConfigFilePathIfExists());
|
|
19
34
|
}
|
|
20
35
|
exports.localConfigFileExists = localConfigFileExists;
|
|
21
36
|
function globalConfigFileExists() {
|
|
22
|
-
return (0, utils_1.doesConfigFileExistAtPath)(
|
|
37
|
+
return (0, utils_1.doesConfigFileExistAtPath)(getGlobalConfigFilePath());
|
|
23
38
|
}
|
|
24
39
|
exports.globalConfigFileExists = globalConfigFileExists;
|
|
25
40
|
function configFileExists() {
|
|
@@ -32,11 +47,11 @@ function configFileExists() {
|
|
|
32
47
|
}
|
|
33
48
|
exports.configFileExists = configFileExists;
|
|
34
49
|
function getConfigDefaultFilePath() {
|
|
35
|
-
const globalConfigFilePath =
|
|
50
|
+
const globalConfigFilePath = getGlobalConfigFilePath();
|
|
36
51
|
if ((0, utils_1.doesConfigFileExistAtPath)(globalConfigFilePath)) {
|
|
37
52
|
return globalConfigFilePath;
|
|
38
53
|
}
|
|
39
|
-
const localConfigFilePath = (
|
|
54
|
+
const localConfigFilePath = getLocalConfigFilePathIfExists();
|
|
40
55
|
if (!localConfigFilePath) {
|
|
41
56
|
throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getDefaultConfigFilePath.error'), config_2.HUBSPOT_CONFIG_ERROR_TYPES.CONFIG_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
|
|
42
57
|
}
|
|
@@ -66,57 +81,61 @@ function getConfig() {
|
|
|
66
81
|
}
|
|
67
82
|
}
|
|
68
83
|
exports.getConfig = getConfig;
|
|
69
|
-
function
|
|
84
|
+
function validateConfig() {
|
|
70
85
|
const config = getConfig();
|
|
71
86
|
if (config.accounts.length === 0) {
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
return {
|
|
88
|
+
isValid: false,
|
|
89
|
+
errors: [(0, lang_1.i18n)('config.validateConfig.missingAccounts')],
|
|
90
|
+
};
|
|
74
91
|
}
|
|
75
92
|
const accountIdsMap = {};
|
|
76
93
|
const accountNamesMap = {};
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
94
|
+
const validationErrors = [];
|
|
95
|
+
config.accounts.forEach(account => {
|
|
96
|
+
const accountValidationResult = (0, utils_1.validateConfigAccount)(account);
|
|
97
|
+
if (!accountValidationResult.isValid) {
|
|
98
|
+
validationErrors.push(...accountValidationResult.errors);
|
|
80
99
|
}
|
|
81
100
|
if (accountIdsMap[account.accountId]) {
|
|
82
|
-
|
|
101
|
+
validationErrors.push((0, lang_1.i18n)('config.validateConfig.duplicateAccountIds', {
|
|
83
102
|
accountId: account.accountId,
|
|
84
103
|
}));
|
|
85
|
-
return false;
|
|
86
104
|
}
|
|
87
105
|
if (account.name) {
|
|
88
106
|
if (accountNamesMap[account.name.toLowerCase()]) {
|
|
89
|
-
|
|
107
|
+
validationErrors.push((0, lang_1.i18n)('config.validateConfig.duplicateAccountNames', {
|
|
90
108
|
accountName: account.name,
|
|
91
109
|
}));
|
|
92
|
-
return false;
|
|
93
110
|
}
|
|
94
111
|
if (/\s+/.test(account.name)) {
|
|
95
|
-
|
|
112
|
+
validationErrors.push((0, lang_1.i18n)('config.validateConfig.invalidAccountName', {
|
|
96
113
|
accountName: account.name,
|
|
97
114
|
}));
|
|
98
|
-
return false;
|
|
99
115
|
}
|
|
100
116
|
accountNamesMap[account.name] = true;
|
|
101
117
|
}
|
|
102
118
|
accountIdsMap[account.accountId] = true;
|
|
103
|
-
return true;
|
|
104
119
|
});
|
|
120
|
+
return { isValid: validationErrors.length === 0, errors: validationErrors };
|
|
105
121
|
}
|
|
106
|
-
exports.
|
|
122
|
+
exports.validateConfig = validateConfig;
|
|
107
123
|
function createEmptyConfigFile(useGlobalConfig = false) {
|
|
108
124
|
const { configFilePathFromEnvironment } = (0, utils_1.getConfigPathEnvironmentVariables)();
|
|
109
125
|
const defaultPath = useGlobalConfig
|
|
110
|
-
?
|
|
126
|
+
? getGlobalConfigFilePath()
|
|
111
127
|
: (0, utils_1.getLocalConfigDefaultFilePath)();
|
|
112
128
|
const pathToWrite = configFilePathFromEnvironment || defaultPath;
|
|
113
|
-
(0, utils_1.writeConfigFile)(
|
|
129
|
+
(0, utils_1.writeConfigFile)(EMPTY_CONFIG, pathToWrite);
|
|
114
130
|
}
|
|
115
131
|
exports.createEmptyConfigFile = createEmptyConfigFile;
|
|
116
|
-
function
|
|
132
|
+
function deleteConfigFileIfEmpty() {
|
|
117
133
|
const pathToDelete = getConfigFilePath();
|
|
118
134
|
try {
|
|
119
|
-
|
|
135
|
+
const config = getConfig();
|
|
136
|
+
if ((0, isDeepEqual_1.isDeepEqual)(config, EMPTY_CONFIG)) {
|
|
137
|
+
fs_extra_1.default.unlinkSync(pathToDelete);
|
|
138
|
+
}
|
|
120
139
|
}
|
|
121
140
|
catch (error) {
|
|
122
141
|
const { message, type } = (0, utils_1.handleConfigFileSystemError)(error, pathToDelete);
|
|
@@ -125,7 +144,7 @@ function deleteConfigFile() {
|
|
|
125
144
|
});
|
|
126
145
|
}
|
|
127
146
|
}
|
|
128
|
-
exports.
|
|
147
|
+
exports.deleteConfigFileIfEmpty = deleteConfigFileIfEmpty;
|
|
129
148
|
function getConfigAccountById(accountId) {
|
|
130
149
|
const { accounts } = getConfig();
|
|
131
150
|
const account = (0, utils_1.getConfigAccountByIdentifier)(accounts, config_1.ACCOUNT_IDENTIFIERS.ACCOUNT_ID, accountId);
|
|
@@ -153,7 +172,7 @@ function getConfigDefaultAccount() {
|
|
|
153
172
|
const { accounts, defaultAccount } = getConfig();
|
|
154
173
|
let defaultAccountToUse = defaultAccount;
|
|
155
174
|
const currentConfigPath = getConfigFilePath();
|
|
156
|
-
const globalConfigPath =
|
|
175
|
+
const globalConfigPath = getGlobalConfigFilePath();
|
|
157
176
|
if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
|
|
158
177
|
const defaultAccountOverrideAccountId = (0, defaultAccountOverride_1.getDefaultAccountOverrideAccountId)();
|
|
159
178
|
defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
|
|
@@ -175,7 +194,7 @@ function getConfigDefaultAccountIfExists() {
|
|
|
175
194
|
let defaultAccountToUse = defaultAccount;
|
|
176
195
|
// Only check for default account override if we're using the global config
|
|
177
196
|
const currentConfigPath = getConfigFilePath();
|
|
178
|
-
const globalConfigPath =
|
|
197
|
+
const globalConfigPath = getGlobalConfigFilePath();
|
|
179
198
|
if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
|
|
180
199
|
const defaultAccountOverrideAccountId = (0, defaultAccountOverride_1.getDefaultAccountOverrideAccountId)();
|
|
181
200
|
defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
|
|
@@ -204,7 +223,7 @@ function getConfigAccountEnvironment(identifier) {
|
|
|
204
223
|
}
|
|
205
224
|
exports.getConfigAccountEnvironment = getConfigAccountEnvironment;
|
|
206
225
|
function addConfigAccount(accountToAdd) {
|
|
207
|
-
if (!(0, utils_1.
|
|
226
|
+
if (!(0, utils_1.validateConfigAccount)(accountToAdd)) {
|
|
208
227
|
throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.addConfigAccount.invalidAccount'), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
|
|
209
228
|
}
|
|
210
229
|
const config = getConfig();
|
|
@@ -219,7 +238,7 @@ function addConfigAccount(accountToAdd) {
|
|
|
219
238
|
}
|
|
220
239
|
exports.addConfigAccount = addConfigAccount;
|
|
221
240
|
function updateConfigAccount(updatedAccount) {
|
|
222
|
-
if (!(0, utils_1.
|
|
241
|
+
if (!(0, utils_1.validateConfigAccount)(updatedAccount)) {
|
|
223
242
|
throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateConfigAccount.invalidAccount', {
|
|
224
243
|
name: updatedAccount.name,
|
|
225
244
|
}), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
|
|
@@ -240,7 +259,7 @@ function setConfigAccountAsDefault(identifier) {
|
|
|
240
259
|
const account = (0, utils_1.getConfigAccountByInferredIdentifier)(config.accounts, identifier);
|
|
241
260
|
if (!account) {
|
|
242
261
|
throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.setConfigAccountAsDefault.accountNotFound', {
|
|
243
|
-
|
|
262
|
+
identifier,
|
|
244
263
|
}), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
|
|
245
264
|
}
|
|
246
265
|
config.defaultAccount = account.accountId;
|
package/config/migrate.d.ts
CHANGED
package/config/migrate.js
CHANGED
|
@@ -3,11 +3,12 @@ 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.mergeConfigAccounts = exports.mergeConfigProperties = exports.migrateConfigAtPath = exports.getConfigAtPath = void 0;
|
|
6
|
+
exports.archiveConfigAtPath = exports.mergeConfigAccounts = exports.mergeConfigProperties = exports.migrateConfigAtPath = exports.getConfigAtPath = void 0;
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const index_1 = require("./index");
|
|
9
9
|
const config_1 = require("../constants/config");
|
|
10
10
|
const utils_1 = require("./utils");
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
11
12
|
function getConfigAtPath(path) {
|
|
12
13
|
const configFileSource = (0, utils_1.readConfigFile)(path);
|
|
13
14
|
return (0, utils_1.parseConfig)(configFileSource, path);
|
|
@@ -16,8 +17,7 @@ exports.getConfigAtPath = getConfigAtPath;
|
|
|
16
17
|
function migrateConfigAtPath(path) {
|
|
17
18
|
(0, index_1.createEmptyConfigFile)(true);
|
|
18
19
|
const configToMigrate = getConfigAtPath(path);
|
|
19
|
-
(0, utils_1.writeConfigFile)(configToMigrate, (0,
|
|
20
|
-
fs_1.default.unlinkSync(path);
|
|
20
|
+
(0, utils_1.writeConfigFile)(configToMigrate, (0, index_1.getGlobalConfigFilePath)());
|
|
21
21
|
}
|
|
22
22
|
exports.migrateConfigAtPath = migrateConfigAtPath;
|
|
23
23
|
function mergeConfigProperties(toConfig, fromConfig, force) {
|
|
@@ -64,7 +64,9 @@ function mergeConfigProperties(toConfig, fromConfig, force) {
|
|
|
64
64
|
config_1.DEFAULT_ACCOUNT,
|
|
65
65
|
];
|
|
66
66
|
propertiesToCheck.forEach(prop => {
|
|
67
|
-
if (toConfig[prop] !== undefined &&
|
|
67
|
+
if (toConfig[prop] !== undefined &&
|
|
68
|
+
fromConfig[prop] !== undefined &&
|
|
69
|
+
toConfig[prop] !== fromConfig[prop]) {
|
|
68
70
|
conflicts.push({
|
|
69
71
|
property: prop,
|
|
70
72
|
oldValue: fromConfig[prop],
|
|
@@ -98,7 +100,13 @@ function buildConfigWithMergedAccounts(toConfig, fromConfig) {
|
|
|
98
100
|
}
|
|
99
101
|
function mergeConfigAccounts(toConfig, fromConfig) {
|
|
100
102
|
const { configWithMergedAccounts, skippedAccountIds } = buildConfigWithMergedAccounts(toConfig, fromConfig);
|
|
101
|
-
(0, utils_1.writeConfigFile)(configWithMergedAccounts, (0,
|
|
103
|
+
(0, utils_1.writeConfigFile)(configWithMergedAccounts, (0, index_1.getGlobalConfigFilePath)());
|
|
102
104
|
return { configWithMergedAccounts, skippedAccountIds };
|
|
103
105
|
}
|
|
104
106
|
exports.mergeConfigAccounts = mergeConfigAccounts;
|
|
107
|
+
function archiveConfigAtPath(configPath) {
|
|
108
|
+
const dir = path_1.default.dirname(configPath);
|
|
109
|
+
const archivedConfigPath = path_1.default.join(dir, config_1.ARCHIVED_HUBSPOT_CONFIG_YAML_FILE_NAME);
|
|
110
|
+
fs_1.default.renameSync(configPath, archivedConfigPath);
|
|
111
|
+
}
|
|
112
|
+
exports.archiveConfigAtPath = archiveConfigAtPath;
|
package/config/utils.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { ACCOUNT_IDENTIFIERS } from '../constants/config';
|
|
2
|
-
import { HubSpotConfig, DeprecatedHubSpotConfigFields, HubSpotConfigErrorType } from '../types/Config';
|
|
3
|
-
import { HubSpotConfigAccount
|
|
2
|
+
import { HubSpotConfig, DeprecatedHubSpotConfigFields, HubSpotConfigErrorType, HubSpotConfigValidationResult } from '../types/Config';
|
|
3
|
+
import { HubSpotConfigAccount } from '../types/Accounts';
|
|
4
4
|
import { ValueOf } from '../types/Utils';
|
|
5
|
-
export declare function getGlobalConfigFilePath(): string;
|
|
6
|
-
export declare function getLocalConfigFilePath(): string | null;
|
|
7
5
|
export declare function getLocalConfigDefaultFilePath(): string;
|
|
8
6
|
export declare function getConfigPathEnvironmentVariables(): {
|
|
9
7
|
useEnvironmentConfig: boolean;
|
|
@@ -12,57 +10,10 @@ export declare function getConfigPathEnvironmentVariables(): {
|
|
|
12
10
|
export declare function doesConfigFileExistAtPath(path: string): boolean;
|
|
13
11
|
export declare function readConfigFile(configPath: string): string;
|
|
14
12
|
export declare function removeUndefinedFieldsFromConfigAccount<T extends HubSpotConfigAccount | Partial<HubSpotConfigAccount> = HubSpotConfigAccount>(account: T): T;
|
|
15
|
-
export declare function formatConfigForWrite(config: HubSpotConfig):
|
|
16
|
-
accounts: ({
|
|
17
|
-
personalAccessKey: string;
|
|
18
|
-
auth: {
|
|
19
|
-
tokenInfo: TokenInfo;
|
|
20
|
-
};
|
|
21
|
-
accountType?: AccountType | undefined;
|
|
22
|
-
defaultCmsPublishMode?: import("../types/Files").CmsPublishMode | undefined;
|
|
23
|
-
parentAccountId?: number | undefined;
|
|
24
|
-
name: string;
|
|
25
|
-
accountId: number;
|
|
26
|
-
env: import("../types/Config").Environment;
|
|
27
|
-
authType: "apikey" | "oauth2" | "personalaccesskey";
|
|
28
|
-
} | {
|
|
29
|
-
auth: {
|
|
30
|
-
clientId: string;
|
|
31
|
-
clientSecret: string;
|
|
32
|
-
scopes: string[];
|
|
33
|
-
tokenInfo: TokenInfo;
|
|
34
|
-
};
|
|
35
|
-
accountType?: AccountType | undefined;
|
|
36
|
-
defaultCmsPublishMode?: import("../types/Files").CmsPublishMode | undefined;
|
|
37
|
-
parentAccountId?: number | undefined;
|
|
38
|
-
name: string;
|
|
39
|
-
accountId: number;
|
|
40
|
-
env: import("../types/Config").Environment;
|
|
41
|
-
authType: "apikey" | "oauth2" | "personalaccesskey";
|
|
42
|
-
} | {
|
|
43
|
-
apiKey: string;
|
|
44
|
-
accountType?: AccountType | undefined;
|
|
45
|
-
defaultCmsPublishMode?: import("../types/Files").CmsPublishMode | undefined;
|
|
46
|
-
parentAccountId?: number | undefined;
|
|
47
|
-
name: string;
|
|
48
|
-
accountId: number;
|
|
49
|
-
env: import("../types/Config").Environment;
|
|
50
|
-
authType: "apikey" | "oauth2" | "personalaccesskey";
|
|
51
|
-
})[];
|
|
52
|
-
allowAutoUpdates?: boolean | undefined;
|
|
53
|
-
defaultMode?: import("../types/Files").CmsPublishMode | undefined;
|
|
54
|
-
env?: import("../types/Config").Environment | undefined;
|
|
55
|
-
httpUseLocalhost?: boolean | undefined;
|
|
56
|
-
autoOpenBrowser?: boolean | undefined;
|
|
57
|
-
useCustomObjectHubfile?: boolean | undefined;
|
|
58
|
-
flags?: string[] | undefined;
|
|
59
|
-
defaultCmsPublishMode: import("../types/Files").CmsPublishMode | undefined;
|
|
60
|
-
httpTimeout: number | undefined;
|
|
61
|
-
allowUsageTracking: boolean | undefined;
|
|
62
|
-
defaultAccount?: number | undefined;
|
|
63
|
-
};
|
|
13
|
+
export declare function formatConfigForWrite(config: HubSpotConfig): HubSpotConfig;
|
|
64
14
|
export declare function writeConfigFile(config: HubSpotConfig, configPath: string): void;
|
|
65
15
|
export declare function normalizeParsedConfig(parsedConfig: HubSpotConfig & DeprecatedHubSpotConfigFields): HubSpotConfig;
|
|
16
|
+
export declare function convertToDeprecatedConfig(config: HubSpotConfig): Partial<HubSpotConfig> & Partial<DeprecatedHubSpotConfigFields>;
|
|
66
17
|
export declare function parseConfig(configSource: string, configPath: string): HubSpotConfig;
|
|
67
18
|
export declare function buildConfigFromEnvironment(): HubSpotConfig;
|
|
68
19
|
export declare function getAccountIdentifierAndType(accountIdentifier: string | number): {
|
|
@@ -72,7 +23,7 @@ export declare function getAccountIdentifierAndType(accountIdentifier: string |
|
|
|
72
23
|
export declare function getConfigAccountByIdentifier(accounts: Array<HubSpotConfigAccount>, identifierFieldName: ValueOf<typeof ACCOUNT_IDENTIFIERS>, identifier: string | number): HubSpotConfigAccount | undefined;
|
|
73
24
|
export declare function getConfigAccountByInferredIdentifier(accounts: Array<HubSpotConfigAccount>, accountIdentifier: string | number): HubSpotConfigAccount | undefined;
|
|
74
25
|
export declare function getConfigAccountIndexById(accounts: Array<HubSpotConfigAccount>, id: number): number;
|
|
75
|
-
export declare function
|
|
26
|
+
export declare function validateConfigAccount(account: Partial<HubSpotConfigAccount>): HubSpotConfigValidationResult;
|
|
76
27
|
export declare function handleConfigFileSystemError(error: unknown, path: string): {
|
|
77
28
|
message?: string;
|
|
78
29
|
type: HubSpotConfigErrorType;
|
package/config/utils.js
CHANGED
|
@@ -3,30 +3,17 @@ 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.handleConfigFileSystemError = exports.
|
|
6
|
+
exports.handleConfigFileSystemError = exports.validateConfigAccount = exports.getConfigAccountIndexById = exports.getConfigAccountByInferredIdentifier = exports.getConfigAccountByIdentifier = exports.getAccountIdentifierAndType = exports.buildConfigFromEnvironment = exports.parseConfig = exports.convertToDeprecatedConfig = exports.normalizeParsedConfig = exports.writeConfigFile = exports.formatConfigForWrite = exports.removeUndefinedFieldsFromConfigAccount = exports.readConfigFile = exports.doesConfigFileExistAtPath = exports.getConfigPathEnvironmentVariables = exports.getLocalConfigDefaultFilePath = void 0;
|
|
7
7
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
8
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
9
|
-
const findup_sync_1 = __importDefault(require("findup-sync"));
|
|
10
9
|
const config_1 = require("../constants/config");
|
|
11
10
|
const auth_1 = require("../constants/auth");
|
|
12
11
|
const FileSystemError_1 = require("../models/FileSystemError");
|
|
13
|
-
const logger_1 = require("../lib/logger");
|
|
14
12
|
const environment_1 = require("../lib/environment");
|
|
15
13
|
const path_1 = require("../lib/path");
|
|
16
14
|
const files_1 = require("../constants/files");
|
|
17
15
|
const lang_1 = require("../utils/lang");
|
|
18
16
|
const HubSpotConfigError_1 = require("../models/HubSpotConfigError");
|
|
19
|
-
function getGlobalConfigFilePath() {
|
|
20
|
-
return config_1.GLOBAL_CONFIG_PATH;
|
|
21
|
-
}
|
|
22
|
-
exports.getGlobalConfigFilePath = getGlobalConfigFilePath;
|
|
23
|
-
function getLocalConfigFilePath() {
|
|
24
|
-
return (0, findup_sync_1.default)([
|
|
25
|
-
config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
|
|
26
|
-
config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME.replace('.yml', '.yaml'),
|
|
27
|
-
], { cwd: (0, path_1.getCwd)() });
|
|
28
|
-
}
|
|
29
|
-
exports.getLocalConfigFilePath = getLocalConfigFilePath;
|
|
30
17
|
function getLocalConfigDefaultFilePath() {
|
|
31
18
|
return `${(0, path_1.getCwd)()}/${config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME}`;
|
|
32
19
|
}
|
|
@@ -104,20 +91,26 @@ function formatConfigForWrite(config) {
|
|
|
104
91
|
...rest,
|
|
105
92
|
accounts: accounts.map(account => {
|
|
106
93
|
const { name, accountId, env, authType, ...rest } = account;
|
|
107
|
-
|
|
94
|
+
const orderedAccount = {
|
|
108
95
|
name,
|
|
109
96
|
accountId,
|
|
110
97
|
env,
|
|
111
98
|
authType,
|
|
112
99
|
...rest,
|
|
100
|
+
// using ...rest messes with the typing
|
|
113
101
|
};
|
|
102
|
+
return removeUndefinedFieldsFromConfigAccount(orderedAccount);
|
|
114
103
|
}),
|
|
115
104
|
};
|
|
116
|
-
return
|
|
105
|
+
return orderedConfig;
|
|
117
106
|
}
|
|
118
107
|
exports.formatConfigForWrite = formatConfigForWrite;
|
|
119
108
|
function writeConfigFile(config, configPath) {
|
|
120
|
-
const
|
|
109
|
+
const formattedConfig = formatConfigForWrite(config);
|
|
110
|
+
const configToWrite = configPath == config_1.GLOBAL_CONFIG_PATH
|
|
111
|
+
? formattedConfig
|
|
112
|
+
: convertToDeprecatedConfig(formattedConfig);
|
|
113
|
+
const source = js_yaml_1.default.dump(configToWrite);
|
|
121
114
|
try {
|
|
122
115
|
fs_extra_1.default.ensureFileSync(configPath);
|
|
123
116
|
fs_extra_1.default.writeFileSync(configPath, source);
|
|
@@ -173,6 +166,30 @@ function normalizeParsedConfig(parsedConfig) {
|
|
|
173
166
|
return parsedConfig;
|
|
174
167
|
}
|
|
175
168
|
exports.normalizeParsedConfig = normalizeParsedConfig;
|
|
169
|
+
function convertToDeprecatedConfig(config) {
|
|
170
|
+
const deprecatedConfig = structuredClone(config);
|
|
171
|
+
if (config.defaultAccount) {
|
|
172
|
+
const defaultAccount = getConfigAccountByIdentifier(config.accounts, config_1.ACCOUNT_IDENTIFIERS.ACCOUNT_ID, config.defaultAccount);
|
|
173
|
+
if (defaultAccount) {
|
|
174
|
+
deprecatedConfig.defaultPortal = defaultAccount.name;
|
|
175
|
+
delete deprecatedConfig.defaultAccount;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const portals = config.accounts.map(account => {
|
|
179
|
+
if (account.accountId) {
|
|
180
|
+
const deprecatedAccount = structuredClone(account);
|
|
181
|
+
deprecatedAccount.portalId = account.accountId;
|
|
182
|
+
// @ts-expect-error deleting accountId is intential since using deprecated config format
|
|
183
|
+
delete deprecatedAccount.accountId;
|
|
184
|
+
return deprecatedAccount;
|
|
185
|
+
}
|
|
186
|
+
return account;
|
|
187
|
+
});
|
|
188
|
+
deprecatedConfig.portals = portals;
|
|
189
|
+
delete deprecatedConfig.accounts;
|
|
190
|
+
return deprecatedConfig;
|
|
191
|
+
}
|
|
192
|
+
exports.convertToDeprecatedConfig = convertToDeprecatedConfig;
|
|
176
193
|
function parseConfig(configSource, configPath) {
|
|
177
194
|
let parsedYaml;
|
|
178
195
|
try {
|
|
@@ -283,57 +300,61 @@ function getConfigAccountByIdentifier(accounts, identifierFieldName, identifier)
|
|
|
283
300
|
exports.getConfigAccountByIdentifier = getConfigAccountByIdentifier;
|
|
284
301
|
function getConfigAccountByInferredIdentifier(accounts, accountIdentifier) {
|
|
285
302
|
const { identifier, identifierType } = getAccountIdentifierAndType(accountIdentifier);
|
|
286
|
-
|
|
303
|
+
const account = getConfigAccountByIdentifier(accounts, identifierType, identifier);
|
|
304
|
+
if (account) {
|
|
305
|
+
return account;
|
|
306
|
+
}
|
|
307
|
+
// Fallback to handle accounts with numbers as names
|
|
308
|
+
return getConfigAccountByIdentifier(accounts, config_1.ACCOUNT_IDENTIFIERS.NAME, String(accountIdentifier));
|
|
287
309
|
}
|
|
288
310
|
exports.getConfigAccountByInferredIdentifier = getConfigAccountByInferredIdentifier;
|
|
289
311
|
function getConfigAccountIndexById(accounts, id) {
|
|
290
312
|
return accounts.findIndex(account => account.accountId === id);
|
|
291
313
|
}
|
|
292
314
|
exports.getConfigAccountIndexById = getConfigAccountIndexById;
|
|
293
|
-
function
|
|
315
|
+
function validateConfigAccount(account) {
|
|
316
|
+
const validationErrors = [];
|
|
294
317
|
if (!account || typeof account !== 'object') {
|
|
295
|
-
|
|
296
|
-
return false;
|
|
318
|
+
validationErrors.push((0, lang_1.i18n)('config.utils.validateConfigAccount.missingAccount'));
|
|
319
|
+
return { isValid: false, errors: validationErrors };
|
|
297
320
|
}
|
|
298
321
|
if (!account.accountId) {
|
|
299
|
-
|
|
300
|
-
return false;
|
|
322
|
+
validationErrors.push((0, lang_1.i18n)('config.utils.validateConfigAccount.missingAccountId'));
|
|
323
|
+
return { isValid: false, errors: validationErrors };
|
|
301
324
|
}
|
|
302
325
|
if (!account.authType) {
|
|
303
|
-
|
|
326
|
+
validationErrors.push((0, lang_1.i18n)('config.utils.validateConfigAccount.missingAuthType', {
|
|
304
327
|
accountId: account.accountId,
|
|
305
328
|
}));
|
|
306
|
-
return false;
|
|
329
|
+
return { isValid: false, errors: validationErrors };
|
|
307
330
|
}
|
|
308
|
-
let valid = false;
|
|
309
331
|
if (account.authType === auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value) {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
logger_1.logger.debug((0, lang_1.i18n)('config.utils.isConfigAccountValid.missingPersonalAccessKey', {
|
|
332
|
+
const isValidPersonalAccessKeyAccount = 'personalAccessKey' in account && Boolean(account.personalAccessKey);
|
|
333
|
+
if (!isValidPersonalAccessKeyAccount) {
|
|
334
|
+
validationErrors.push((0, lang_1.i18n)('config.utils.validateConfigAccount.missingPersonalAccessKey', {
|
|
314
335
|
accountId: account.accountId,
|
|
315
336
|
}));
|
|
316
337
|
}
|
|
317
338
|
}
|
|
318
339
|
if (account.authType === auth_1.OAUTH_AUTH_METHOD.value) {
|
|
319
|
-
|
|
320
|
-
if (!
|
|
321
|
-
|
|
340
|
+
const isValidOAuthAccount = 'auth' in account && Boolean(account.auth);
|
|
341
|
+
if (!isValidOAuthAccount) {
|
|
342
|
+
validationErrors.push((0, lang_1.i18n)('config.utils.validateConfigAccount.missingAuth', {
|
|
322
343
|
accountId: account.accountId,
|
|
323
344
|
}));
|
|
324
345
|
}
|
|
325
346
|
}
|
|
326
347
|
if (account.authType === auth_1.API_KEY_AUTH_METHOD.value) {
|
|
327
|
-
|
|
328
|
-
if (!
|
|
329
|
-
|
|
348
|
+
const isValidAPIKeyAccount = 'apiKey' in account && Boolean(account.apiKey);
|
|
349
|
+
if (!isValidAPIKeyAccount) {
|
|
350
|
+
validationErrors.push((0, lang_1.i18n)('config.utils.validateConfigAccount.missingApiKey', {
|
|
330
351
|
accountId: account.accountId,
|
|
331
352
|
}));
|
|
332
353
|
}
|
|
333
354
|
}
|
|
334
|
-
return
|
|
355
|
+
return { isValid: validationErrors.length === 0, errors: validationErrors };
|
|
335
356
|
}
|
|
336
|
-
exports.
|
|
357
|
+
exports.validateConfigAccount = validateConfigAccount;
|
|
337
358
|
function handleConfigFileSystemError(error, path) {
|
|
338
359
|
let message;
|
|
339
360
|
let type = config_1.HUBSPOT_CONFIG_ERROR_TYPES.UNKNOWN;
|
package/errors/index.d.ts
CHANGED
|
@@ -13,9 +13,9 @@ export declare function isMissingScopeError(err: unknown): err is HubSpotHttpErr
|
|
|
13
13
|
export declare function isGatingError(err: unknown): err is HubSpotHttpError;
|
|
14
14
|
export declare function isTimeoutError(err: unknown): err is HubSpotHttpError;
|
|
15
15
|
export declare function isAuthError(err: unknown): err is HubSpotHttpError;
|
|
16
|
-
export declare function isValidationError(err: unknown):
|
|
16
|
+
export declare function isValidationError(err: unknown): err is HubSpotHttpError;
|
|
17
17
|
export declare function isHubSpotHttpError(error?: unknown): error is HubSpotHttpError;
|
|
18
|
-
export declare function isGithubRateLimitError(err: unknown):
|
|
18
|
+
export declare function isGithubRateLimitError(err: unknown): err is HubSpotHttpError;
|
|
19
19
|
export declare function isSystemError(err: unknown): err is BaseError;
|
|
20
20
|
export declare function isFileSystemError(err: unknown): err is FileSystemError;
|
|
21
21
|
export declare function isHubSpotConfigError(err: unknown): err is HubSpotConfigError;
|
package/errors/index.js
CHANGED
|
@@ -45,7 +45,7 @@ function isValidationError(err) {
|
|
|
45
45
|
}
|
|
46
46
|
exports.isValidationError = isValidationError;
|
|
47
47
|
function isHubSpotHttpError(error) {
|
|
48
|
-
return !!error && error instanceof HubSpotHttpError_1.
|
|
48
|
+
return (!!error && error instanceof Error && error.name === HubSpotHttpError_1.HubSpotHttpErrorName);
|
|
49
49
|
}
|
|
50
50
|
exports.isHubSpotHttpError = isHubSpotHttpError;
|
|
51
51
|
function isGithubRateLimitError(err) {
|
|
@@ -68,7 +68,7 @@ function isSystemError(err) {
|
|
|
68
68
|
}
|
|
69
69
|
exports.isSystemError = isSystemError;
|
|
70
70
|
function isFileSystemError(err) {
|
|
71
|
-
return err instanceof FileSystemError_1.
|
|
71
|
+
return err instanceof Error && err.name === FileSystemError_1.FilerSystemErrorName;
|
|
72
72
|
}
|
|
73
73
|
exports.isFileSystemError = isFileSystemError;
|
|
74
74
|
function isHubSpotConfigError(err) {
|
package/http/getAxiosConfig.d.ts
CHANGED
|
@@ -6,4 +6,6 @@ export declare const USER_AGENTS: {
|
|
|
6
6
|
export declare function getDefaultUserAgentHeader(): {
|
|
7
7
|
'User-Agent': string;
|
|
8
8
|
};
|
|
9
|
+
export declare function hostnameMatchesNoProxyPattern(hostname: string, pattern: string): boolean;
|
|
10
|
+
export declare function shouldUseProxy(baseURL: string): boolean;
|
|
9
11
|
export declare function getAxiosConfig(options: HttpOptions): AxiosRequestConfig;
|
package/http/getAxiosConfig.js
CHANGED
|
@@ -3,12 +3,14 @@ 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.getAxiosConfig = exports.getDefaultUserAgentHeader = exports.USER_AGENTS = void 0;
|
|
6
|
+
exports.getAxiosConfig = exports.shouldUseProxy = exports.hostnameMatchesNoProxyPattern = exports.getDefaultUserAgentHeader = exports.USER_AGENTS = void 0;
|
|
7
7
|
const package_json_1 = require("../package.json");
|
|
8
8
|
const config_1 = require("../config");
|
|
9
9
|
const urls_1 = require("../lib/urls");
|
|
10
|
-
const https_1 = __importDefault(require("https"));
|
|
11
10
|
const http_1 = __importDefault(require("http"));
|
|
11
|
+
const https_1 = __importDefault(require("https"));
|
|
12
|
+
const http_proxy_agent_1 = require("http-proxy-agent");
|
|
13
|
+
const https_proxy_agent_1 = require("https-proxy-agent");
|
|
12
14
|
// Total number of sockets across all hosts
|
|
13
15
|
const MAX_TOTAL_SOCKETS = 25;
|
|
14
16
|
// Total number of sockets per each host
|
|
@@ -23,6 +25,39 @@ const httpsAgent = new https_1.default.Agent({
|
|
|
23
25
|
maxTotalSockets: MAX_TOTAL_SOCKETS,
|
|
24
26
|
maxSockets: MAX_SOCKETS_PER_HOST,
|
|
25
27
|
});
|
|
28
|
+
function getHttpProxyEnvVariable() {
|
|
29
|
+
return process.env.HTTP_PROXY || process.env.http_proxy;
|
|
30
|
+
}
|
|
31
|
+
function getHttpsProxyEnvVariable() {
|
|
32
|
+
return process.env.HTTPS_PROXY || process.env.https_proxy;
|
|
33
|
+
}
|
|
34
|
+
function getAllProxyEnvVariable() {
|
|
35
|
+
return process.env.ALL_PROXY || process.env.all_proxy;
|
|
36
|
+
}
|
|
37
|
+
function getHttpProxyAgent() {
|
|
38
|
+
const proxyUrl = getHttpProxyEnvVariable() || getAllProxyEnvVariable();
|
|
39
|
+
if (!proxyUrl) {
|
|
40
|
+
return httpAgent;
|
|
41
|
+
}
|
|
42
|
+
return new http_proxy_agent_1.HttpProxyAgent(proxyUrl, {
|
|
43
|
+
keepAlive: true,
|
|
44
|
+
maxTotalSockets: MAX_TOTAL_SOCKETS,
|
|
45
|
+
maxSockets: MAX_SOCKETS_PER_HOST,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function getHttpsProxyAgent() {
|
|
49
|
+
const proxyUrl = getHttpProxyEnvVariable() ||
|
|
50
|
+
getHttpsProxyEnvVariable() ||
|
|
51
|
+
getAllProxyEnvVariable();
|
|
52
|
+
if (!proxyUrl) {
|
|
53
|
+
return httpsAgent;
|
|
54
|
+
}
|
|
55
|
+
return new https_proxy_agent_1.HttpsProxyAgent(proxyUrl, {
|
|
56
|
+
keepAlive: true,
|
|
57
|
+
maxTotalSockets: MAX_TOTAL_SOCKETS,
|
|
58
|
+
maxSockets: MAX_SOCKETS_PER_HOST,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
26
61
|
exports.USER_AGENTS = {
|
|
27
62
|
'HubSpot Local Dev Lib': package_json_1.version,
|
|
28
63
|
};
|
|
@@ -39,6 +74,37 @@ exports.getDefaultUserAgentHeader = getDefaultUserAgentHeader;
|
|
|
39
74
|
const DEFAULT_TRANSITIONAL = {
|
|
40
75
|
clarifyTimeoutError: true,
|
|
41
76
|
};
|
|
77
|
+
function hostnameMatchesNoProxyPattern(hostname, pattern) {
|
|
78
|
+
const hostnameNormalized = hostname.toLowerCase();
|
|
79
|
+
const patternNormalized = pattern.trim().toLowerCase();
|
|
80
|
+
if (patternNormalized === '*') {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
if (patternNormalized.startsWith('.')) {
|
|
84
|
+
return hostnameNormalized.endsWith(patternNormalized);
|
|
85
|
+
}
|
|
86
|
+
return (hostnameNormalized === patternNormalized || // exact match (e.g. "api.hubapi.com" matches "api.hubapi.com")
|
|
87
|
+
hostnameNormalized.endsWith(`.${patternNormalized}`) // domain suffix match (e.g. "api.hubapi.com" matches ".hubapi.com")
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
exports.hostnameMatchesNoProxyPattern = hostnameMatchesNoProxyPattern;
|
|
91
|
+
function shouldUseProxy(baseURL) {
|
|
92
|
+
if (!getHttpProxyEnvVariable() &&
|
|
93
|
+
!getHttpsProxyEnvVariable() &&
|
|
94
|
+
!getAllProxyEnvVariable()) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const noProxy = process.env.NO_PROXY || process.env.no_proxy;
|
|
98
|
+
if (noProxy) {
|
|
99
|
+
const hostname = new URL(baseURL).hostname;
|
|
100
|
+
const noProxyList = noProxy.split(',').filter(Boolean);
|
|
101
|
+
if (noProxyList.some(pattern => hostnameMatchesNoProxyPattern(hostname, pattern))) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
exports.shouldUseProxy = shouldUseProxy;
|
|
42
108
|
function getAxiosConfig(options) {
|
|
43
109
|
const { env, localHostOverride, headers, ...rest } = options;
|
|
44
110
|
let config;
|
|
@@ -56,16 +122,19 @@ function getAxiosConfig(options) {
|
|
|
56
122
|
if (config && config.httpUseLocalhost) {
|
|
57
123
|
httpUseLocalhost = config.httpUseLocalhost;
|
|
58
124
|
}
|
|
125
|
+
const baseURL = (0, urls_1.getHubSpotApiOrigin)(env, localHostOverride ? false : httpUseLocalhost);
|
|
59
126
|
return {
|
|
60
|
-
baseURL
|
|
127
|
+
baseURL,
|
|
61
128
|
headers: {
|
|
62
129
|
...getDefaultUserAgentHeader(),
|
|
63
130
|
...(headers || {}),
|
|
64
131
|
},
|
|
65
132
|
timeout: httpTimeout,
|
|
66
133
|
transitional: DEFAULT_TRANSITIONAL,
|
|
67
|
-
|
|
68
|
-
|
|
134
|
+
// Disable axios's built-in proxy handling - we use custom agents instead
|
|
135
|
+
proxy: false,
|
|
136
|
+
httpAgent: shouldUseProxy(baseURL) ? getHttpProxyAgent() : httpAgent,
|
|
137
|
+
httpsAgent: shouldUseProxy(baseURL) ? getHttpsProxyAgent() : httpsAgent,
|
|
69
138
|
...rest,
|
|
70
139
|
};
|
|
71
140
|
}
|
package/http/index.js
CHANGED
|
@@ -41,6 +41,7 @@ const lang_1 = require("../utils/lang");
|
|
|
41
41
|
const HubSpotHttpError_1 = require("../models/HubSpotHttpError");
|
|
42
42
|
const auth_1 = require("../constants/auth");
|
|
43
43
|
const localDevAuth_1 = require("../api/localDevAuth");
|
|
44
|
+
const fireAlarm_1 = require("../api/fireAlarm");
|
|
44
45
|
const util = __importStar(require("util"));
|
|
45
46
|
const trackUsage_1 = require("../lib/trackUsage");
|
|
46
47
|
const i18nKey = 'http.index';
|
|
@@ -48,14 +49,15 @@ const IGNORE_URLS_NETWORK_DEBUG = [
|
|
|
48
49
|
localDevAuth_1.LOCALDEVAUTH_ACCESS_TOKEN_PATH,
|
|
49
50
|
trackUsage_1.CMS_CLI_USAGE_PATH,
|
|
50
51
|
trackUsage_1.VSCODE_USAGE_PATH,
|
|
52
|
+
fireAlarm_1.FIREALARM_API_AUTH_PATH,
|
|
51
53
|
];
|
|
52
54
|
function logRequest(response) {
|
|
53
55
|
try {
|
|
54
56
|
if (!process.env.HUBSPOT_NETWORK_LOGGING) {
|
|
55
57
|
return;
|
|
56
58
|
}
|
|
57
|
-
if (
|
|
58
|
-
IGNORE_URLS_NETWORK_DEBUG.
|
|
59
|
+
if (!process.env.HUBSPOT_DEBUG_LOGGING_VERBOSE &&
|
|
60
|
+
IGNORE_URLS_NETWORK_DEBUG.some(url => response?.config?.url && response.config.url.includes(url))) {
|
|
59
61
|
return;
|
|
60
62
|
}
|
|
61
63
|
logger_1.logger.debug(util.inspect({
|
|
@@ -82,6 +84,13 @@ axios_1.default.interceptors.response.use((response) => {
|
|
|
82
84
|
catch (e) {
|
|
83
85
|
// Ignore any errors that occur while logging the response
|
|
84
86
|
}
|
|
87
|
+
// Don't re-wrap if already a HubSpotHttpError. This can happen when
|
|
88
|
+
// multiple copies of local-dev-lib are loaded and share the same axios
|
|
89
|
+
// instance, causing multiple interceptors to be registered.
|
|
90
|
+
if (error instanceof HubSpotHttpError_1.HubSpotHttpError ||
|
|
91
|
+
error?.name === HubSpotHttpError_1.HubSpotHttpErrorName) {
|
|
92
|
+
return Promise.reject(error);
|
|
93
|
+
}
|
|
85
94
|
// Wrap all axios errors in our own Error class. Attach the error
|
|
86
95
|
// as the cause for the new error, so we maintain the stack trace
|
|
87
96
|
return Promise.reject(new HubSpotHttpError_1.HubSpotHttpError(error.message, { cause: error }));
|
package/lang/en.json
CHANGED
|
@@ -251,11 +251,11 @@
|
|
|
251
251
|
"error": "No config file found.",
|
|
252
252
|
"errorWithPath": "No config file found at {{ path }}."
|
|
253
253
|
},
|
|
254
|
-
"
|
|
255
|
-
"missingAccounts": "
|
|
256
|
-
"duplicateAccountIds": "
|
|
257
|
-
"duplicateAccountNames": "
|
|
258
|
-
"invalidAccountName": "
|
|
254
|
+
"validateConfig": {
|
|
255
|
+
"missingAccounts": "No accounts found",
|
|
256
|
+
"duplicateAccountIds": "Multiple accounts with accountId: {{ accountId }}",
|
|
257
|
+
"duplicateAccountNames": "Multiple accounts with name: {{ accountName }}",
|
|
258
|
+
"invalidAccountName": "Account name {{ accountName }} contains spaces"
|
|
259
259
|
},
|
|
260
260
|
"getConfigAccountById": {
|
|
261
261
|
"error": "No account with id {{ accountId }} exists in config"
|
|
@@ -276,7 +276,7 @@
|
|
|
276
276
|
"accountNotFound": "Attempting to update account with id {{ id }}, but that account was not found in config"
|
|
277
277
|
},
|
|
278
278
|
"setConfigAccountAsDefault": {
|
|
279
|
-
"accountNotFound": "Attempted to set account with
|
|
279
|
+
"accountNotFound": "Attempted to set account with identifier {{ identifier }} as default, but that account was not found in config"
|
|
280
280
|
},
|
|
281
281
|
"renameConfigAccount": {
|
|
282
282
|
"accountNotFound": "Attempted to rename account with name {{ currentName }}, but that account was not found in config",
|
|
@@ -299,13 +299,13 @@
|
|
|
299
299
|
"configNotFoundError": "No config file found at {{ path }}.",
|
|
300
300
|
"insufficientPermissionsError": "Insufficient permissions to access config file at {{ path }}"
|
|
301
301
|
},
|
|
302
|
-
"
|
|
303
|
-
"missingAccount": "
|
|
304
|
-
"missingAuthType": "
|
|
305
|
-
"missingAccountId": "
|
|
306
|
-
"missingApiKey": "
|
|
307
|
-
"missingAuth": "
|
|
308
|
-
"missingPersonalAccessKey": "
|
|
302
|
+
"validateConfigAccount": {
|
|
303
|
+
"missingAccount": "At least one account in config is missing data",
|
|
304
|
+
"missingAuthType": "Account {{ accountId }} has no authType",
|
|
305
|
+
"missingAccountId": "At least one account in config is missing accountId",
|
|
306
|
+
"missingApiKey": "Account {{ accountId }} has authType of apikey but is missing the apiKey field",
|
|
307
|
+
"missingAuth": "Account {{ accountId }} has authtype of oauth2 but is missing auth data",
|
|
308
|
+
"missingPersonalAccessKey": "Account {{ accountId }} has authType of personalAccessKey but is missing the personalAccessKey field"
|
|
309
309
|
},
|
|
310
310
|
"getConfigPathEnvironmentVariables": {
|
|
311
311
|
"invalidEnvironmentVariables": "USE_ENVIRONMENT_HUBSPOT_CONFIG and HUBSPOT_CONFIG_PATH cannot both be set simultaneously"
|
package/lib/personalAccessKey.js
CHANGED
|
@@ -121,7 +121,7 @@ async function authorizedScopesForPortalAndUser(accountId) {
|
|
|
121
121
|
exports.authorizedScopesForPortalAndUser = authorizedScopesForPortalAndUser;
|
|
122
122
|
async function updateConfigWithAccessToken(token, personalAccessKey, env, name, makeDefault = false) {
|
|
123
123
|
const { portalId, accessToken, expiresAt, accountType } = token;
|
|
124
|
-
const account =
|
|
124
|
+
const account = (0, config_1.getConfigAccountIfExists)(portalId);
|
|
125
125
|
const accountEnv = env || account?.env || environments_1.ENVIRONMENTS.PROD;
|
|
126
126
|
let parentAccountId;
|
|
127
127
|
try {
|
|
@@ -159,12 +159,12 @@ async function updateConfigWithAccessToken(token, personalAccessKey, env, name,
|
|
|
159
159
|
accountId: portalId,
|
|
160
160
|
accountType,
|
|
161
161
|
personalAccessKey,
|
|
162
|
-
name: name || account?.name
|
|
162
|
+
name: name || account?.name,
|
|
163
163
|
authType: auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value,
|
|
164
164
|
auth: { tokenInfo: { accessToken, expiresAt } },
|
|
165
165
|
parentAccountId,
|
|
166
166
|
env: accountEnv,
|
|
167
|
-
};
|
|
167
|
+
}; // Account may temporarily not have a name before prompted to add one in the CLI
|
|
168
168
|
// Add new account if it doesn't exist, otherwise update existing account
|
|
169
169
|
if (account) {
|
|
170
170
|
(0, config_1.updateConfigAccount)(updatedAccount);
|
package/lib/portManager.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RequestPortsData } from '../types/PortManager';
|
|
1
|
+
import { RequestPortsData, ServerPortMap } from '../types/PortManager';
|
|
2
2
|
export declare const BASE_URL: string;
|
|
3
3
|
export declare function isPortManagerPortAvailable(): Promise<boolean>;
|
|
4
4
|
export declare function isPortManagerServerRunning(): Promise<boolean>;
|
|
@@ -7,6 +7,7 @@ export declare function stopPortManagerServer(): Promise<void>;
|
|
|
7
7
|
export declare function requestPorts(portData: Array<RequestPortsData>): Promise<{
|
|
8
8
|
[instanceId: string]: number;
|
|
9
9
|
}>;
|
|
10
|
+
export declare function getActiveServers(): Promise<ServerPortMap>;
|
|
10
11
|
export declare function getServerPortByInstanceId(serverInstanceId: string): Promise<number>;
|
|
11
12
|
export declare function deleteServerInstance(serverInstanceId: string): Promise<void>;
|
|
12
13
|
export declare function portManagerHasActiveServers(): Promise<boolean>;
|
package/lib/portManager.js
CHANGED
|
@@ -3,7 +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.portManagerHasActiveServers = exports.deleteServerInstance = exports.getServerPortByInstanceId = exports.requestPorts = exports.stopPortManagerServer = exports.startPortManagerServer = exports.isPortManagerServerRunning = exports.isPortManagerPortAvailable = exports.BASE_URL = void 0;
|
|
6
|
+
exports.portManagerHasActiveServers = exports.deleteServerInstance = exports.getServerPortByInstanceId = exports.getActiveServers = exports.requestPorts = exports.stopPortManagerServer = exports.startPortManagerServer = exports.isPortManagerServerRunning = exports.isPortManagerPortAvailable = exports.BASE_URL = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const PortManagerServer_1 = require("../utils/PortManagerServer");
|
|
9
9
|
const ports_1 = require("../constants/ports");
|
|
@@ -45,6 +45,11 @@ async function requestPorts(portData) {
|
|
|
45
45
|
return data.ports;
|
|
46
46
|
}
|
|
47
47
|
exports.requestPorts = requestPorts;
|
|
48
|
+
async function getActiveServers() {
|
|
49
|
+
const { data } = await axios_1.default.get(`${exports.BASE_URL}/servers`);
|
|
50
|
+
return data.servers;
|
|
51
|
+
}
|
|
52
|
+
exports.getActiveServers = getActiveServers;
|
|
48
53
|
async function getServerPortByInstanceId(serverInstanceId) {
|
|
49
54
|
const { data } = await axios_1.default.get(`${exports.BASE_URL}/servers/${serverInstanceId}`);
|
|
50
55
|
return data.port;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FileSystemError = void 0;
|
|
3
|
+
exports.FileSystemError = exports.FilerSystemErrorName = void 0;
|
|
4
4
|
const lang_1 = require("../utils/lang");
|
|
5
5
|
const errors_1 = require("../errors");
|
|
6
6
|
const i18nKey = 'errors.fileSystemErrors';
|
|
7
|
+
exports.FilerSystemErrorName = 'FilerSystemError';
|
|
7
8
|
class FileSystemError extends Error {
|
|
8
9
|
context;
|
|
9
10
|
constructor(options, context) {
|
|
10
11
|
super('', options);
|
|
11
|
-
this.name =
|
|
12
|
+
this.name = exports.FilerSystemErrorName;
|
|
12
13
|
this.context = context;
|
|
13
14
|
if (context) {
|
|
14
15
|
let fileAction = '';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HubSpotHttpErrorContext } from '../types/Error';
|
|
2
|
+
export declare const HubSpotHttpErrorName = "HubSpotHttpError";
|
|
2
3
|
export declare class HubSpotHttpError<T = any> extends Error {
|
|
3
4
|
status?: number;
|
|
4
5
|
code?: string;
|
|
@@ -17,7 +18,7 @@ export declare class HubSpotHttpError<T = any> extends Error {
|
|
|
17
18
|
timeout?: number;
|
|
18
19
|
correlationId?: string;
|
|
19
20
|
constructor(message?: string, options?: ErrorOptions, context?: HubSpotHttpErrorContext);
|
|
20
|
-
updateContext(context: Partial<HubSpotHttpErrorContext
|
|
21
|
+
updateContext(context: Partial<HubSpotHttpErrorContext>, additionalDebugContext?: string): void;
|
|
21
22
|
toString(): string;
|
|
22
23
|
formattedValidationErrors(): string;
|
|
23
24
|
private extractDerivedContext;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HubSpotHttpError = void 0;
|
|
3
|
+
exports.HubSpotHttpError = exports.HubSpotHttpErrorName = void 0;
|
|
4
4
|
const axios_1 = require("axios");
|
|
5
5
|
const api_1 = require("../constants/api");
|
|
6
6
|
const lang_1 = require("../utils/lang");
|
|
7
|
+
exports.HubSpotHttpErrorName = 'HubSpotHttpError';
|
|
7
8
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
9
|
class HubSpotHttpError extends Error {
|
|
9
10
|
status;
|
|
@@ -22,7 +23,7 @@ class HubSpotHttpError extends Error {
|
|
|
22
23
|
correlationId;
|
|
23
24
|
constructor(message, options, context) {
|
|
24
25
|
super(message, options);
|
|
25
|
-
this.name =
|
|
26
|
+
this.name = exports.HubSpotHttpErrorName;
|
|
26
27
|
this.context = context;
|
|
27
28
|
this.cause = options?.cause;
|
|
28
29
|
if (options && (0, axios_1.isAxiosError)(options.cause)) {
|
|
@@ -60,11 +61,11 @@ class HubSpotHttpError extends Error {
|
|
|
60
61
|
this.message = messages.join(' ');
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
|
-
updateContext(context) {
|
|
64
|
+
updateContext(context, additionalDebugContext) {
|
|
64
65
|
this.context = { ...this.context, ...context };
|
|
65
66
|
// Update the error messages when the context is updated
|
|
66
67
|
if ((0, axios_1.isAxiosError)(this.cause)) {
|
|
67
|
-
this.message = this.joinErrorMessages(this.cause, this.context);
|
|
68
|
+
this.message = this.joinErrorMessages(this.cause, this.context, additionalDebugContext);
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
toString() {
|
|
@@ -137,8 +138,7 @@ class HubSpotHttpError extends Error {
|
|
|
137
138
|
}
|
|
138
139
|
this.validationErrors = errorMessages;
|
|
139
140
|
}
|
|
140
|
-
joinErrorMessages(error, context = {}) {
|
|
141
|
-
const i18nKey = 'errors.apiErrors';
|
|
141
|
+
joinErrorMessages(error, context = {}, additionalDebugContext) {
|
|
142
142
|
const status = error.response?.status;
|
|
143
143
|
const method = error.config?.method;
|
|
144
144
|
let messageDetail;
|
|
@@ -149,48 +149,68 @@ class HubSpotHttpError extends Error {
|
|
|
149
149
|
const requestName = context.request
|
|
150
150
|
? `${action} ${preposition} '${context.request}'`
|
|
151
151
|
: action;
|
|
152
|
-
messageDetail = (0, lang_1.i18n)(
|
|
152
|
+
messageDetail = (0, lang_1.i18n)(`errors.apiErrors.messageDetail`, {
|
|
153
153
|
accountId: context.accountId,
|
|
154
154
|
requestName,
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
157
|
else {
|
|
158
|
-
messageDetail = (0, lang_1.i18n)(
|
|
158
|
+
messageDetail = (0, lang_1.i18n)(`errors.apiErrors.genericMessageDetail`);
|
|
159
159
|
}
|
|
160
160
|
const errorMessage = [];
|
|
161
161
|
if ((method === 'put' || method === 'post') && context.payload) {
|
|
162
|
-
errorMessage.push((0, lang_1.i18n)(
|
|
162
|
+
errorMessage.push((0, lang_1.i18n)(`errors.apiErrors.unableToUpload`, { payload: context.payload }));
|
|
163
163
|
}
|
|
164
|
+
let statusBasedMessage;
|
|
164
165
|
switch (status) {
|
|
165
166
|
case 400:
|
|
166
|
-
|
|
167
|
+
statusBasedMessage = (0, lang_1.i18n)(`errors.apiErrors.codes.400`, {
|
|
168
|
+
messageDetail,
|
|
169
|
+
});
|
|
167
170
|
break;
|
|
168
171
|
case 401:
|
|
169
|
-
|
|
172
|
+
statusBasedMessage = (0, lang_1.i18n)(`errors.apiErrors.codes.401`, {
|
|
173
|
+
messageDetail,
|
|
174
|
+
});
|
|
170
175
|
break;
|
|
171
176
|
case 403:
|
|
172
177
|
break;
|
|
173
178
|
case 404:
|
|
174
|
-
|
|
179
|
+
statusBasedMessage = (0, lang_1.i18n)(`errors.apiErrors.codes.404`, {
|
|
180
|
+
messageDetail,
|
|
181
|
+
});
|
|
175
182
|
break;
|
|
176
183
|
case 429:
|
|
177
|
-
|
|
184
|
+
statusBasedMessage = (0, lang_1.i18n)(`errors.apiErrors.codes.429`, {
|
|
185
|
+
messageDetail,
|
|
186
|
+
});
|
|
178
187
|
break;
|
|
179
188
|
case 503:
|
|
180
|
-
|
|
189
|
+
statusBasedMessage = (0, lang_1.i18n)(`errors.apiErrors.codes.503`, {
|
|
190
|
+
messageDetail,
|
|
191
|
+
});
|
|
181
192
|
break;
|
|
182
193
|
default:
|
|
183
194
|
if (status && status >= 500 && status < 600) {
|
|
184
|
-
|
|
195
|
+
statusBasedMessage = (0, lang_1.i18n)(`errors.apiErrors.codes.500Generic`, {
|
|
196
|
+
messageDetail,
|
|
197
|
+
});
|
|
185
198
|
}
|
|
186
199
|
else if (status && status >= 400 && status < 500) {
|
|
187
|
-
|
|
200
|
+
statusBasedMessage = (0, lang_1.i18n)(`errors.apiErrors.codes.400Generic`, {
|
|
201
|
+
messageDetail,
|
|
202
|
+
});
|
|
188
203
|
}
|
|
189
204
|
else {
|
|
190
|
-
|
|
205
|
+
statusBasedMessage = (0, lang_1.i18n)(`errors.apiErrors.codes.generic`, {
|
|
206
|
+
messageDetail,
|
|
207
|
+
});
|
|
191
208
|
}
|
|
192
209
|
break;
|
|
193
210
|
}
|
|
211
|
+
if (statusBasedMessage) {
|
|
212
|
+
errorMessage.push(`${statusBasedMessage}${additionalDebugContext ? ` ${additionalDebugContext}` : ''}`);
|
|
213
|
+
}
|
|
194
214
|
if (error?.response?.data) {
|
|
195
215
|
const { message, errors } = error.response.data;
|
|
196
216
|
if (message) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/local-dev-lib",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1-experimental.0",
|
|
4
4
|
"description": "Provides library functionality for HubSpot local development tooling, including the HubSpot CLI",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
-
"build": "
|
|
14
|
+
"build": "tsx ./scripts/build.ts",
|
|
15
15
|
"lint": "eslint --max-warnings=0 . && prettier . --check",
|
|
16
16
|
"local-dev": "yarn build && cd dist && yarn link && cd .. && tsc --watch --rootDir . --outdir dist",
|
|
17
17
|
"prettier:write": "prettier . --write",
|
|
18
|
-
"release": "
|
|
18
|
+
"release": "tsx ./scripts/release.ts release",
|
|
19
19
|
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ./node_modules/.bin/jest"
|
|
20
20
|
},
|
|
21
21
|
"license": "Apache-2.0",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"jest": "^29.5.0",
|
|
40
40
|
"open": "^8.4.2",
|
|
41
41
|
"ts-jest": "^29.0.5",
|
|
42
|
-
"
|
|
42
|
+
"tsx": "^4.20.6",
|
|
43
43
|
"typescript": "^4.9.5",
|
|
44
44
|
"yargs": "^17.7.2"
|
|
45
45
|
},
|
|
@@ -73,6 +73,8 @@
|
|
|
73
73
|
"findup-sync": "5.0.0",
|
|
74
74
|
"form-data": "^4.0.4",
|
|
75
75
|
"fs-extra": "11.2.0",
|
|
76
|
+
"http-proxy-agent": "7.0.2",
|
|
77
|
+
"https-proxy-agent": "7.0.6",
|
|
76
78
|
"ignore": "5.3.1",
|
|
77
79
|
"js-yaml": "4.1.0",
|
|
78
80
|
"moment": "2.30.1",
|
package/types/Config.d.ts
CHANGED
|
@@ -34,3 +34,7 @@ export type HubSpotState = {
|
|
|
34
34
|
};
|
|
35
35
|
export type HubSpotConfigErrorType = ValueOf<typeof HUBSPOT_CONFIG_ERROR_TYPES>;
|
|
36
36
|
export type HubSpotConfigOperation = ValueOf<typeof HUBSPOT_CONFIG_OPERATIONS>;
|
|
37
|
+
export type HubSpotConfigValidationResult = {
|
|
38
|
+
isValid: boolean;
|
|
39
|
+
errors: Array<string>;
|
|
40
|
+
};
|
package/types/Deploy.d.ts
CHANGED
|
@@ -35,13 +35,6 @@ export type DeployStatusTaskLocator = {
|
|
|
35
35
|
status: string;
|
|
36
36
|
}>;
|
|
37
37
|
};
|
|
38
|
-
export type ProjectDeployResponseQueued = {
|
|
39
|
-
id: string;
|
|
40
|
-
buildResultType: 'DEPLOY_QUEUED';
|
|
41
|
-
links: {
|
|
42
|
-
status: string;
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
38
|
export type SubdeployValidationIssue = {
|
|
46
39
|
uid: string;
|
|
47
40
|
componentTypeName: string;
|
|
@@ -51,8 +44,20 @@ export type SubdeployValidationIssue = {
|
|
|
51
44
|
isWarning: boolean;
|
|
52
45
|
}[];
|
|
53
46
|
};
|
|
47
|
+
export type DeployResponseLinks = {
|
|
48
|
+
status: string;
|
|
49
|
+
};
|
|
50
|
+
export type ProjectDeployResponseQueued = {
|
|
51
|
+
id: string;
|
|
52
|
+
buildResultType: 'DEPLOY_QUEUED';
|
|
53
|
+
links: DeployResponseLinks;
|
|
54
|
+
};
|
|
54
55
|
export type ProjectDeployResponseBlocked = {
|
|
55
56
|
buildResultType: 'DEPLOY_BLOCKED';
|
|
56
57
|
issues: SubdeployValidationIssue[];
|
|
57
58
|
};
|
|
58
59
|
export type ProjectDeployResponse = ProjectDeployResponseQueued | ProjectDeployResponseBlocked;
|
|
60
|
+
export type ProjectDeployResponseV1 = {
|
|
61
|
+
id: string;
|
|
62
|
+
links: DeployResponseLinks;
|
|
63
|
+
};
|
package/utils/git.js
CHANGED
|
@@ -12,8 +12,9 @@ const GITIGNORE_FILE = '.gitignore';
|
|
|
12
12
|
function makeComparisonDir(filepath) {
|
|
13
13
|
if (typeof filepath !== 'string')
|
|
14
14
|
return null;
|
|
15
|
+
let dir = path_1.default.dirname(path_1.default.resolve(filepath)).toLowerCase();
|
|
15
16
|
// Append sep to make comparisons easier e.g. 'foos'.startsWith('foo')
|
|
16
|
-
return
|
|
17
|
+
return dir + (!dir.endsWith(path_1.default.sep) ? path_1.default.sep : '');
|
|
17
18
|
}
|
|
18
19
|
function getGitComparisonDir() {
|
|
19
20
|
return makeComparisonDir((0, findup_sync_1.default)('.git'));
|