@hubspot/local-dev-lib 0.5.0-experimental.0 → 0.5.0-experimental.10

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/config/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { CmsPublishMode } from '../types/Files';
4
4
  import { Environment } from '../types/Config';
5
5
  export declare function localConfigFileExists(): boolean;
6
6
  export declare function globalConfigFileExists(): boolean;
7
+ export declare function configFileExists(): boolean;
7
8
  export declare function getConfigFilePath(): string;
8
9
  export declare function getConfig(): HubSpotConfig;
9
10
  export declare function isConfigValid(): boolean;
@@ -15,7 +16,7 @@ export declare function getConfigAccountIfExists(identifier: number | string): H
15
16
  export declare function getConfigDefaultAccount(): HubSpotConfigAccount;
16
17
  export declare function getConfigDefaultAccountIfExists(): HubSpotConfigAccount | undefined;
17
18
  export declare function getAllConfigAccounts(): HubSpotConfigAccount[];
18
- export declare function getConfigAccountEnvironment(identifier?: number | string): Environment;
19
+ export declare function getConfigAccountEnvironment(identifier: number | string): Environment;
19
20
  export declare function addConfigAccount(accountToAdd: HubSpotConfigAccount): void;
20
21
  export declare function updateConfigAccount(updatedAccount: HubSpotConfigAccount): void;
21
22
  export declare function setConfigAccountAsDefault(identifier: number | string): void;
@@ -23,7 +24,7 @@ export declare function renameConfigAccount(currentName: string, newName: string
23
24
  export declare function removeAccountFromConfig(accountId: number): void;
24
25
  export declare function updateHttpTimeout(timeout: string | number): void;
25
26
  export declare function updateAllowUsageTracking(isAllowed: boolean): void;
26
- export declare function updateAllowAutoUpdates(enabled: boolean): void;
27
+ export declare function updateAllowAutoUpdates(isEnabled: boolean): void;
27
28
  export declare function updateAutoOpenBrowser(isEnabled: boolean): void;
28
29
  export declare function updateDefaultCmsPublishMode(cmsPublishMode: CmsPublishMode): void;
29
30
  export declare function isConfigFlagEnabled(flag: ConfigFlag, defaultValue?: boolean): boolean;
package/config/index.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.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.deleteConfigFile = exports.createEmptyConfigFile = exports.isConfigValid = exports.getConfig = exports.getConfigFilePath = exports.globalConfigFileExists = exports.localConfigFileExists = void 0;
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.deleteConfigFile = exports.createEmptyConfigFile = exports.isConfigValid = exports.getConfig = exports.getConfigFilePath = exports.configFileExists = exports.globalConfigFileExists = exports.localConfigFileExists = void 0;
7
7
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
8
  const config_1 = require("../constants/config");
9
9
  const logger_1 = require("../lib/logger");
@@ -12,22 +12,33 @@ const files_1 = require("../constants/files");
12
12
  const lang_1 = require("../utils/lang");
13
13
  const defaultAccountOverride_1 = require("./defaultAccountOverride");
14
14
  const environment_1 = require("../lib/environment");
15
+ const HubSpotConfigError_1 = require("../models/HubSpotConfigError");
16
+ const config_2 = require("../constants/config");
15
17
  function localConfigFileExists() {
16
18
  return Boolean((0, utils_1.getLocalConfigFilePath)());
17
19
  }
18
20
  exports.localConfigFileExists = localConfigFileExists;
19
21
  function globalConfigFileExists() {
20
- return fs_extra_1.default.existsSync((0, utils_1.getGlobalConfigFilePath)());
22
+ return (0, utils_1.doesConfigFileExistAtPath)((0, utils_1.getGlobalConfigFilePath)());
21
23
  }
22
24
  exports.globalConfigFileExists = globalConfigFileExists;
25
+ function configFileExists() {
26
+ try {
27
+ return (0, utils_1.doesConfigFileExistAtPath)(getConfigFilePath());
28
+ }
29
+ catch (error) {
30
+ return false;
31
+ }
32
+ }
33
+ exports.configFileExists = configFileExists;
23
34
  function getConfigDefaultFilePath() {
24
35
  const globalConfigFilePath = (0, utils_1.getGlobalConfigFilePath)();
25
- if (fs_extra_1.default.existsSync(globalConfigFilePath)) {
36
+ if ((0, utils_1.doesConfigFileExistAtPath)(globalConfigFilePath)) {
26
37
  return globalConfigFilePath;
27
38
  }
28
39
  const localConfigFilePath = (0, utils_1.getLocalConfigFilePath)();
29
40
  if (!localConfigFilePath) {
30
- throw new Error((0, lang_1.i18n)('config.getDefaultConfigFilePath.error'));
41
+ 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);
31
42
  }
32
43
  return localConfigFilePath;
33
44
  }
@@ -37,14 +48,22 @@ function getConfigFilePath() {
37
48
  }
38
49
  exports.getConfigFilePath = getConfigFilePath;
39
50
  function getConfig() {
40
- const { useEnvironmentConfig } = (0, utils_1.getConfigPathEnvironmentVariables)();
41
- if (useEnvironmentConfig) {
42
- return (0, utils_1.buildConfigFromEnvironment)();
43
- }
44
- const pathToRead = getConfigFilePath();
45
- logger_1.logger.debug((0, lang_1.i18n)('config.getConfig', { path: pathToRead }));
46
- const configFileSource = (0, utils_1.readConfigFile)(pathToRead);
47
- return (0, utils_1.parseConfig)(configFileSource);
51
+ let pathToRead;
52
+ try {
53
+ const { useEnvironmentConfig } = (0, utils_1.getConfigPathEnvironmentVariables)();
54
+ if (useEnvironmentConfig) {
55
+ return (0, utils_1.buildConfigFromEnvironment)();
56
+ }
57
+ pathToRead = getConfigFilePath();
58
+ logger_1.logger.debug((0, lang_1.i18n)('config.getConfig.reading', { path: pathToRead }));
59
+ const configFileSource = (0, utils_1.readConfigFile)(pathToRead);
60
+ return (0, utils_1.parseConfig)(configFileSource, pathToRead);
61
+ }
62
+ catch (err) {
63
+ throw new HubSpotConfigError_1.HubSpotConfigError(pathToRead
64
+ ? (0, lang_1.i18n)('config.getConfig.errorWithPath', { path: pathToRead })
65
+ : (0, lang_1.i18n)('config.getConfig.error'), config_2.HUBSPOT_CONFIG_ERROR_TYPES.CONFIG_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ, { cause: err });
66
+ }
48
67
  }
49
68
  exports.getConfig = getConfig;
50
69
  function isConfigValid() {
@@ -96,14 +115,22 @@ function createEmptyConfigFile(useGlobalConfig = false) {
96
115
  exports.createEmptyConfigFile = createEmptyConfigFile;
97
116
  function deleteConfigFile() {
98
117
  const pathToDelete = getConfigFilePath();
99
- fs_extra_1.default.unlinkSync(pathToDelete);
118
+ try {
119
+ fs_extra_1.default.unlinkSync(pathToDelete);
120
+ }
121
+ catch (error) {
122
+ const { message, type } = (0, utils_1.handleConfigFileSystemError)(error, pathToDelete);
123
+ throw new HubSpotConfigError_1.HubSpotConfigError(message, type, config_1.HUBSPOT_CONFIG_OPERATIONS.DELETE, {
124
+ cause: error,
125
+ });
126
+ }
100
127
  }
101
128
  exports.deleteConfigFile = deleteConfigFile;
102
129
  function getConfigAccountById(accountId) {
103
130
  const { accounts } = getConfig();
104
131
  const account = (0, utils_1.getConfigAccountByIdentifier)(accounts, config_1.ACCOUNT_IDENTIFIERS.ACCOUNT_ID, accountId);
105
132
  if (!account) {
106
- throw new Error((0, lang_1.i18n)('config.getConfigAccountById.error', { accountId }));
133
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigAccountById.error', { accountId }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
107
134
  }
108
135
  return account;
109
136
  }
@@ -112,7 +139,7 @@ function getConfigAccountByName(accountName) {
112
139
  const { accounts } = getConfig();
113
140
  const account = (0, utils_1.getConfigAccountByIdentifier)(accounts, config_1.ACCOUNT_IDENTIFIERS.NAME, accountName);
114
141
  if (!account) {
115
- throw new Error((0, lang_1.i18n)('config.getConfigAccountByName.error', { accountName }));
142
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigAccountByName.error', { accountName }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
116
143
  }
117
144
  return account;
118
145
  }
@@ -125,18 +152,20 @@ exports.getConfigAccountIfExists = getConfigAccountIfExists;
125
152
  function getConfigDefaultAccount() {
126
153
  const { accounts, defaultAccount } = getConfig();
127
154
  let defaultAccountToUse = defaultAccount;
128
- if (globalConfigFileExists()) {
155
+ const currentConfigPath = getConfigFilePath();
156
+ const globalConfigPath = (0, utils_1.getGlobalConfigFilePath)();
157
+ if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
129
158
  const defaultAccountOverrideAccountId = (0, defaultAccountOverride_1.getDefaultAccountOverrideAccountId)();
130
159
  defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
131
160
  }
132
161
  if (!defaultAccountToUse) {
133
- throw new Error((0, lang_1.i18n)('config.getConfigDefaultAccount.fieldMissingError'));
162
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigDefaultAccount.fieldMissingError'), config_2.HUBSPOT_CONFIG_ERROR_TYPES.NO_DEFAULT_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
134
163
  }
135
164
  const account = (0, utils_1.getConfigAccountByInferredIdentifier)(accounts, defaultAccountToUse);
136
165
  if (!account) {
137
- throw new Error((0, lang_1.i18n)('config.getConfigDefaultAccount.accountMissingError', {
166
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigDefaultAccount.accountMissingError', {
138
167
  defaultAccountToUse,
139
- }));
168
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
140
169
  }
141
170
  return account;
142
171
  }
@@ -144,7 +173,10 @@ exports.getConfigDefaultAccount = getConfigDefaultAccount;
144
173
  function getConfigDefaultAccountIfExists() {
145
174
  const { accounts, defaultAccount } = getConfig();
146
175
  let defaultAccountToUse = defaultAccount;
147
- if (globalConfigFileExists()) {
176
+ // Only check for default account override if we're using the global config
177
+ const currentConfigPath = getConfigFilePath();
178
+ const globalConfigPath = (0, utils_1.getGlobalConfigFilePath)();
179
+ if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
148
180
  const defaultAccountOverrideAccountId = (0, defaultAccountOverride_1.getDefaultAccountOverrideAccountId)();
149
181
  defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
150
182
  }
@@ -161,27 +193,26 @@ function getAllConfigAccounts() {
161
193
  }
162
194
  exports.getAllConfigAccounts = getAllConfigAccounts;
163
195
  function getConfigAccountEnvironment(identifier) {
164
- if (identifier) {
165
- const config = getConfig();
166
- const account = (0, utils_1.getConfigAccountByInferredIdentifier)(config.accounts, identifier);
167
- if (account) {
168
- return (0, environment_1.getValidEnv)(account.env);
169
- }
196
+ const config = getConfig();
197
+ const account = (0, utils_1.getConfigAccountByInferredIdentifier)(config.accounts, identifier);
198
+ if (!account) {
199
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigAccountEnvironment.accountNotFound', {
200
+ identifier,
201
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
170
202
  }
171
- const defaultAccount = getConfigDefaultAccount();
172
- return (0, environment_1.getValidEnv)(defaultAccount.env);
203
+ return (0, environment_1.getValidEnv)(account.env);
173
204
  }
174
205
  exports.getConfigAccountEnvironment = getConfigAccountEnvironment;
175
206
  function addConfigAccount(accountToAdd) {
176
207
  if (!(0, utils_1.isConfigAccountValid)(accountToAdd)) {
177
- throw new Error((0, lang_1.i18n)('config.addConfigAccount.invalidAccount'));
208
+ 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);
178
209
  }
179
210
  const config = getConfig();
180
211
  const accountInConfig = (0, utils_1.getConfigAccountByIdentifier)(config.accounts, config_1.ACCOUNT_IDENTIFIERS.ACCOUNT_ID, accountToAdd.accountId);
181
212
  if (accountInConfig) {
182
- throw new Error((0, lang_1.i18n)('config.addConfigAccount.duplicateAccount', {
213
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.addConfigAccount.duplicateAccount', {
183
214
  accountId: accountToAdd.accountId,
184
- }));
215
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
185
216
  }
186
217
  config.accounts.push(accountToAdd);
187
218
  (0, utils_1.writeConfigFile)(config, getConfigFilePath());
@@ -189,14 +220,16 @@ function addConfigAccount(accountToAdd) {
189
220
  exports.addConfigAccount = addConfigAccount;
190
221
  function updateConfigAccount(updatedAccount) {
191
222
  if (!(0, utils_1.isConfigAccountValid)(updatedAccount)) {
192
- throw new Error((0, lang_1.i18n)('config.updateConfigAccount.invalidAccount'));
223
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateConfigAccount.invalidAccount', {
224
+ name: updatedAccount.name,
225
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
193
226
  }
194
227
  const config = getConfig();
195
228
  const accountIndex = (0, utils_1.getConfigAccountIndexById)(config.accounts, updatedAccount.accountId);
196
229
  if (accountIndex < 0) {
197
- throw new Error((0, lang_1.i18n)('config.updateConfigAccount.accountNotFound', {
230
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateConfigAccount.accountNotFound', {
198
231
  accountId: updatedAccount.accountId,
199
- }));
232
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
200
233
  }
201
234
  config.accounts[accountIndex] = updatedAccount;
202
235
  (0, utils_1.writeConfigFile)(config, getConfigFilePath());
@@ -206,9 +239,9 @@ function setConfigAccountAsDefault(identifier) {
206
239
  const config = getConfig();
207
240
  const account = (0, utils_1.getConfigAccountByInferredIdentifier)(config.accounts, identifier);
208
241
  if (!account) {
209
- throw new Error((0, lang_1.i18n)('config.setConfigAccountAsDefault.accountNotFound', {
242
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.setConfigAccountAsDefault.accountNotFound', {
210
243
  accountId: identifier,
211
- }));
244
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
212
245
  }
213
246
  config.defaultAccount = account.accountId;
214
247
  (0, utils_1.writeConfigFile)(config, getConfigFilePath());
@@ -218,15 +251,16 @@ function renameConfigAccount(currentName, newName) {
218
251
  const config = getConfig();
219
252
  const account = (0, utils_1.getConfigAccountByIdentifier)(config.accounts, config_1.ACCOUNT_IDENTIFIERS.NAME, currentName);
220
253
  if (!account) {
221
- throw new Error((0, lang_1.i18n)('config.renameConfigAccount.accountNotFound', {
254
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.renameConfigAccount.accountNotFound', {
222
255
  currentName,
223
- }));
256
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
224
257
  }
225
258
  const duplicateAccount = (0, utils_1.getConfigAccountByIdentifier)(config.accounts, config_1.ACCOUNT_IDENTIFIERS.NAME, newName);
226
259
  if (duplicateAccount) {
227
- throw new Error((0, lang_1.i18n)('config.renameConfigAccount.duplicateAccount', {
260
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.renameConfigAccount.duplicateAccount', {
261
+ currentName,
228
262
  newName,
229
- }));
263
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
230
264
  }
231
265
  account.name = newName;
232
266
  (0, utils_1.writeConfigFile)(config, getConfigFilePath());
@@ -236,9 +270,9 @@ function removeAccountFromConfig(accountId) {
236
270
  const config = getConfig();
237
271
  const index = (0, utils_1.getConfigAccountIndexById)(config.accounts, accountId);
238
272
  if (index < 0) {
239
- throw new Error((0, lang_1.i18n)('config.removeAccountFromConfig.accountNotFound', {
273
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.removeAccountFromConfig.accountNotFound', {
240
274
  accountId,
241
- }));
275
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
242
276
  }
243
277
  config.accounts.splice(index, 1);
244
278
  if (config.defaultAccount === accountId) {
@@ -250,9 +284,10 @@ exports.removeAccountFromConfig = removeAccountFromConfig;
250
284
  function updateHttpTimeout(timeout) {
251
285
  const parsedTimeout = typeof timeout === 'string' ? parseInt(timeout) : timeout;
252
286
  if (isNaN(parsedTimeout) || parsedTimeout < config_1.MIN_HTTP_TIMEOUT) {
253
- throw new Error((0, lang_1.i18n)('config.updateHttpTimeout.invalidTimeout', {
287
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateHttpTimeout.invalidTimeout', {
254
288
  minTimeout: config_1.MIN_HTTP_TIMEOUT,
255
- }));
289
+ timeout: parsedTimeout,
290
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
256
291
  }
257
292
  const config = getConfig();
258
293
  config.httpTimeout = parsedTimeout;
@@ -260,22 +295,32 @@ function updateHttpTimeout(timeout) {
260
295
  }
261
296
  exports.updateHttpTimeout = updateHttpTimeout;
262
297
  function updateAllowUsageTracking(isAllowed) {
298
+ if (typeof isAllowed !== 'boolean') {
299
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateAllowUsageTracking.invalidInput', {
300
+ isAllowed: `${isAllowed}`,
301
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
302
+ }
263
303
  const config = getConfig();
264
304
  config.allowUsageTracking = isAllowed;
265
305
  (0, utils_1.writeConfigFile)(config, getConfigFilePath());
266
306
  }
267
307
  exports.updateAllowUsageTracking = updateAllowUsageTracking;
268
- function updateAllowAutoUpdates(enabled) {
308
+ function updateAllowAutoUpdates(isEnabled) {
309
+ if (typeof isEnabled !== 'boolean') {
310
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateAllowAutoUpdates.invalidInput', {
311
+ isEnabled: `${isEnabled}`,
312
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
313
+ }
269
314
  const config = getConfig();
270
- config.allowAutoUpdates = enabled;
315
+ config.allowAutoUpdates = isEnabled;
271
316
  (0, utils_1.writeConfigFile)(config, getConfigFilePath());
272
317
  }
273
318
  exports.updateAllowAutoUpdates = updateAllowAutoUpdates;
274
319
  function updateAutoOpenBrowser(isEnabled) {
275
320
  if (typeof isEnabled !== 'boolean') {
276
- throw new Error((0, lang_1.i18n)('config.updateAutoOpenBrowser.invalidInput', {
321
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateAutoOpenBrowser.invalidInput', {
277
322
  isEnabled: `${isEnabled}`,
278
- }));
323
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
279
324
  }
280
325
  const config = getConfig();
281
326
  config.autoOpenBrowser = isEnabled;
@@ -285,7 +330,9 @@ exports.updateAutoOpenBrowser = updateAutoOpenBrowser;
285
330
  function updateDefaultCmsPublishMode(cmsPublishMode) {
286
331
  if (!cmsPublishMode ||
287
332
  !Object.values(files_1.CMS_PUBLISH_MODE).includes(cmsPublishMode)) {
288
- throw new Error((0, lang_1.i18n)('config.updateDefaultCmsPublishMode.invalidCmsPublishMode'));
333
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateDefaultCmsPublishMode.invalidCmsPublishMode', {
334
+ cmsPublishMode,
335
+ }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
289
336
  }
290
337
  const config = getConfig();
291
338
  config.defaultCmsPublishMode = cmsPublishMode;
package/config/migrate.js CHANGED
@@ -10,7 +10,7 @@ const config_1 = require("../constants/config");
10
10
  const utils_1 = require("./utils");
11
11
  function getConfigAtPath(path) {
12
12
  const configFileSource = (0, utils_1.readConfigFile)(path);
13
- return (0, utils_1.parseConfig)(configFileSource);
13
+ return (0, utils_1.parseConfig)(configFileSource, path);
14
14
  }
15
15
  exports.getConfigAtPath = getConfigAtPath;
16
16
  function migrateConfigAtPath(path) {
package/config/state.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { CLIState } from '../types/Config';
2
- export declare function getStateValue<K extends keyof CLIState>(key: K): CLIState[K];
3
- export declare function setStateValue<K extends keyof CLIState>(key: K, value: CLIState[K]): void;
1
+ import { HubSpotState } from '../types/Config';
2
+ export declare function getStateValue<K extends keyof HubSpotState>(key: K): HubSpotState[K];
3
+ export declare function setStateValue<K extends keyof HubSpotState>(key: K, value: HubSpotState[K]): void;
package/config/state.js CHANGED
@@ -29,9 +29,10 @@ const path = __importStar(require("path"));
29
29
  const lang_1 = require("../utils/lang");
30
30
  const config_1 = require("../constants/config");
31
31
  const logger_1 = require("../lib/logger");
32
+ const config_2 = require("../constants/config");
32
33
  const i18nKey = 'config.state';
33
34
  const DEFAULT_STATE = {
34
- mcpTotalToolCalls: 0,
35
+ [config_2.MCP_TOTAL_TOOL_CALLS_STATE]: 0,
35
36
  };
36
37
  function ensureCLIDirectory() {
37
38
  try {
@@ -46,19 +47,41 @@ function ensureCLIDirectory() {
46
47
  }));
47
48
  }
48
49
  }
50
+ function sanitizeAndMerge(parsed) {
51
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
52
+ return structuredClone(DEFAULT_STATE);
53
+ }
54
+ const state = parsed;
55
+ const result = structuredClone(DEFAULT_STATE);
56
+ for (const key in DEFAULT_STATE) {
57
+ const typedKey = key;
58
+ if (key in state &&
59
+ typeof state[typedKey] === typeof DEFAULT_STATE[typedKey]) {
60
+ result[typedKey] = state[typedKey];
61
+ }
62
+ // keys not in parsed file remain as DEFAULT values
63
+ }
64
+ return result;
65
+ }
49
66
  function getCurrentState() {
50
67
  try {
51
- if (fs.existsSync(config_1.STATE_FILE_PATH)) {
52
- const data = fs.readFileSync(config_1.STATE_FILE_PATH, 'utf-8');
53
- return JSON.parse(data);
68
+ if (!fs.existsSync(config_1.STATE_FILE_PATH)) {
69
+ return structuredClone(DEFAULT_STATE);
54
70
  }
71
+ const data = fs.readFileSync(config_1.STATE_FILE_PATH, 'utf-8');
72
+ if (!data?.trim()) {
73
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.getCurrentState.debug.emptyStateFile`));
74
+ return structuredClone(DEFAULT_STATE);
75
+ }
76
+ const parsed = JSON.parse(data);
77
+ return sanitizeAndMerge(parsed);
55
78
  }
56
79
  catch (error) {
57
- throw new Error((0, lang_1.i18n)(`${i18nKey}.getCurrentState.errors.errorReading`, {
80
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.getCurrentState.errors.errorReading`, {
58
81
  error: error instanceof Error ? error.message : String(error),
59
82
  }));
83
+ return structuredClone(DEFAULT_STATE);
60
84
  }
61
- return DEFAULT_STATE;
62
85
  }
63
86
  function getStateValue(key) {
64
87
  ensureCLIDirectory();
@@ -68,13 +91,7 @@ function getStateValue(key) {
68
91
  exports.getStateValue = getStateValue;
69
92
  function setStateValue(key, value) {
70
93
  ensureCLIDirectory();
71
- let currentState = DEFAULT_STATE;
72
- try {
73
- currentState = getCurrentState();
74
- }
75
- catch (error) {
76
- logger_1.logger.debug(error);
77
- }
94
+ const currentState = getCurrentState();
78
95
  const newState = { ...currentState, [key]: value };
79
96
  try {
80
97
  fs.writeFileSync(config_1.STATE_FILE_PATH, JSON.stringify(newState, null, 2), 'utf-8');
package/config/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ACCOUNT_IDENTIFIERS } from '../constants/config';
2
- import { HubSpotConfig, DeprecatedHubSpotConfigFields } from '../types/Config';
2
+ import { HubSpotConfig, DeprecatedHubSpotConfigFields, HubSpotConfigErrorType } from '../types/Config';
3
3
  import { HubSpotConfigAccount, AccountType, TokenInfo } from '../types/Accounts';
4
4
  import { ValueOf } from '../types/Utils';
5
5
  export declare function getGlobalConfigFilePath(): string;
@@ -9,6 +9,7 @@ export declare function getConfigPathEnvironmentVariables(): {
9
9
  useEnvironmentConfig: boolean;
10
10
  configFilePathFromEnvironment: string | undefined;
11
11
  };
12
+ export declare function doesConfigFileExistAtPath(path: string): boolean;
12
13
  export declare function readConfigFile(configPath: string): string;
13
14
  export declare function removeUndefinedFieldsFromConfigAccount<T extends HubSpotConfigAccount | Partial<HubSpotConfigAccount> = HubSpotConfigAccount>(account: T): T;
14
15
  export declare function formatConfigForWrite(config: HubSpotConfig): {
@@ -62,7 +63,7 @@ export declare function formatConfigForWrite(config: HubSpotConfig): {
62
63
  };
63
64
  export declare function writeConfigFile(config: HubSpotConfig, configPath: string): void;
64
65
  export declare function normalizeParsedConfig(parsedConfig: HubSpotConfig & DeprecatedHubSpotConfigFields): HubSpotConfig;
65
- export declare function parseConfig(configSource: string): HubSpotConfig;
66
+ export declare function parseConfig(configSource: string, configPath: string): HubSpotConfig;
66
67
  export declare function buildConfigFromEnvironment(): HubSpotConfig;
67
68
  export declare function getAccountIdentifierAndType(accountIdentifier: string | number): {
68
69
  identifier: string | number;
@@ -72,3 +73,7 @@ export declare function getConfigAccountByIdentifier(accounts: Array<HubSpotConf
72
73
  export declare function getConfigAccountByInferredIdentifier(accounts: Array<HubSpotConfigAccount>, accountIdentifier: string | number): HubSpotConfigAccount | undefined;
73
74
  export declare function getConfigAccountIndexById(accounts: Array<HubSpotConfigAccount>, id: number): number;
74
75
  export declare function isConfigAccountValid(account: Partial<HubSpotConfigAccount>): boolean;
76
+ export declare function handleConfigFileSystemError(error: unknown, path: string): {
77
+ message?: string;
78
+ type: HubSpotConfigErrorType;
79
+ };
package/config/utils.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.isConfigAccountValid = exports.getConfigAccountIndexById = exports.getConfigAccountByInferredIdentifier = exports.getConfigAccountByIdentifier = exports.getAccountIdentifierAndType = exports.buildConfigFromEnvironment = exports.parseConfig = exports.normalizeParsedConfig = exports.writeConfigFile = exports.formatConfigForWrite = exports.removeUndefinedFieldsFromConfigAccount = exports.readConfigFile = exports.getConfigPathEnvironmentVariables = exports.getLocalConfigDefaultFilePath = exports.getLocalConfigFilePath = exports.getGlobalConfigFilePath = void 0;
6
+ exports.handleConfigFileSystemError = exports.isConfigAccountValid = exports.getConfigAccountIndexById = exports.getConfigAccountByInferredIdentifier = exports.getConfigAccountByIdentifier = exports.getAccountIdentifierAndType = exports.buildConfigFromEnvironment = exports.parseConfig = exports.normalizeParsedConfig = exports.writeConfigFile = exports.formatConfigForWrite = exports.removeUndefinedFieldsFromConfigAccount = exports.readConfigFile = exports.doesConfigFileExistAtPath = exports.getConfigPathEnvironmentVariables = exports.getLocalConfigDefaultFilePath = exports.getLocalConfigFilePath = exports.getGlobalConfigFilePath = void 0;
7
7
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
8
  const js_yaml_1 = __importDefault(require("js-yaml"));
9
9
  const findup_sync_1 = __importDefault(require("findup-sync"));
@@ -15,6 +15,7 @@ const environment_1 = require("../lib/environment");
15
15
  const path_1 = require("../lib/path");
16
16
  const files_1 = require("../constants/files");
17
17
  const lang_1 = require("../utils/lang");
18
+ const HubSpotConfigError_1 = require("../models/HubSpotConfigError");
18
19
  function getGlobalConfigFilePath() {
19
20
  return config_1.GLOBAL_CONFIG_PATH;
20
21
  }
@@ -23,7 +24,7 @@ function getLocalConfigFilePath() {
23
24
  return (0, findup_sync_1.default)([
24
25
  config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
25
26
  config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME.replace('.yml', '.yaml'),
26
- ]);
27
+ ], { cwd: (0, path_1.getCwd)() });
27
28
  }
28
29
  exports.getLocalConfigFilePath = getLocalConfigFilePath;
29
30
  function getLocalConfigDefaultFilePath() {
@@ -35,7 +36,7 @@ function getConfigPathEnvironmentVariables() {
35
36
  const useEnvironmentConfig = process.env[config_1.ENVIRONMENT_VARIABLES.USE_ENVIRONMENT_HUBSPOT_CONFIG] ===
36
37
  'true';
37
38
  if (configFilePathFromEnvironment && useEnvironmentConfig) {
38
- throw new Error((0, lang_1.i18n)('config.utils.getConfigPathEnvironmentVariables.invalidEnvironmentVariables'));
39
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.utils.getConfigPathEnvironmentVariables.invalidEnvironmentVariables'), config_1.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ENVIRONMENT_VARIABLES, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
39
40
  }
40
41
  return {
41
42
  configFilePathFromEnvironment,
@@ -43,18 +44,24 @@ function getConfigPathEnvironmentVariables() {
43
44
  };
44
45
  }
45
46
  exports.getConfigPathEnvironmentVariables = getConfigPathEnvironmentVariables;
47
+ function doesConfigFileExistAtPath(path) {
48
+ try {
49
+ return fs_extra_1.default.existsSync(path);
50
+ }
51
+ catch (error) {
52
+ const { message, type } = handleConfigFileSystemError(error, path);
53
+ throw new HubSpotConfigError_1.HubSpotConfigError(message, type, config_1.HUBSPOT_CONFIG_OPERATIONS.READ, { cause: error });
54
+ }
55
+ }
56
+ exports.doesConfigFileExistAtPath = doesConfigFileExistAtPath;
46
57
  function readConfigFile(configPath) {
47
- let source = '';
48
58
  try {
49
- source = fs_extra_1.default.readFileSync(configPath).toString();
59
+ return fs_extra_1.default.readFileSync(configPath).toString();
50
60
  }
51
61
  catch (err) {
52
- throw new FileSystemError_1.FileSystemError({ cause: err }, {
53
- filepath: configPath,
54
- operation: 'read',
55
- });
62
+ const { message, type } = handleConfigFileSystemError(err, configPath);
63
+ throw new HubSpotConfigError_1.HubSpotConfigError(message, type, config_1.HUBSPOT_CONFIG_OPERATIONS.READ, { cause: err });
56
64
  }
57
- return source;
58
65
  }
59
66
  exports.readConfigFile = readConfigFile;
60
67
  function removeUndefinedFieldsFromConfigAccount(account) {
@@ -110,7 +117,7 @@ function formatConfigForWrite(config) {
110
117
  }
111
118
  exports.formatConfigForWrite = formatConfigForWrite;
112
119
  function writeConfigFile(config, configPath) {
113
- const source = js_yaml_1.default.dump(JSON.parse(JSON.stringify(formatConfigForWrite(config), null, 2)));
120
+ const source = js_yaml_1.default.dump(formatConfigForWrite(config));
114
121
  try {
115
122
  fs_extra_1.default.ensureFileSync(configPath);
116
123
  fs_extra_1.default.writeFileSync(configPath, source);
@@ -135,6 +142,9 @@ function getAccountType(sandboxAccountType) {
135
142
  return config_1.HUBSPOT_ACCOUNT_TYPES.STANDARD;
136
143
  }
137
144
  function normalizeParsedConfig(parsedConfig) {
145
+ if (!parsedConfig.portals && !parsedConfig.accounts) {
146
+ parsedConfig.accounts = [];
147
+ }
138
148
  if (parsedConfig.portals) {
139
149
  parsedConfig.accounts = parsedConfig.portals.map(account => {
140
150
  if (account.portalId) {
@@ -163,13 +173,13 @@ function normalizeParsedConfig(parsedConfig) {
163
173
  return parsedConfig;
164
174
  }
165
175
  exports.normalizeParsedConfig = normalizeParsedConfig;
166
- function parseConfig(configSource) {
176
+ function parseConfig(configSource, configPath) {
167
177
  let parsedYaml;
168
178
  try {
169
179
  parsedYaml = js_yaml_1.default.load(configSource);
170
180
  }
171
181
  catch (err) {
172
- throw new Error((0, lang_1.i18n)('config.utils.parseConfig.error'), { cause: err });
182
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.utils.parseConfig.error', { configPath: configPath }), config_1.HUBSPOT_CONFIG_ERROR_TYPES.YAML_PARSING, config_1.HUBSPOT_CONFIG_OPERATIONS.READ, { cause: err });
173
183
  }
174
184
  return normalizeParsedConfig(parsedYaml);
175
185
  }
@@ -188,7 +198,7 @@ function buildConfigFromEnvironment() {
188
198
  const allowUsageTrackingVar = process.env[config_1.ENVIRONMENT_VARIABLES.ALLOW_USAGE_TRACKING];
189
199
  const defaultCmsPublishModeVar = process.env[config_1.ENVIRONMENT_VARIABLES.DEFAULT_CMS_PUBLISH_MODE];
190
200
  if (!accountIdVar) {
191
- throw new Error((0, lang_1.i18n)('config.utils.buildConfigFromEnvironment.missingAccountId'));
201
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.utils.buildConfigFromEnvironment.missingAccountId'), config_1.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ENVIRONMENT_VARIABLES, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
192
202
  }
193
203
  const accountId = parseInt(accountIdVar);
194
204
  const httpTimeout = httpTimeoutVar ? parseInt(httpTimeoutVar) : undefined;
@@ -242,7 +252,7 @@ function buildConfigFromEnvironment() {
242
252
  };
243
253
  }
244
254
  else {
245
- throw new Error((0, lang_1.i18n)('config.utils.buildConfigFromEnvironment.invalidAuthType'));
255
+ throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.utils.buildConfigFromEnvironment.invalidAuthType'), config_1.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ENVIRONMENT_VARIABLES, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
246
256
  }
247
257
  return {
248
258
  accounts: [account],
@@ -324,3 +334,19 @@ function isConfigAccountValid(account) {
324
334
  return valid;
325
335
  }
326
336
  exports.isConfigAccountValid = isConfigAccountValid;
337
+ function handleConfigFileSystemError(error, path) {
338
+ let message;
339
+ let type = config_1.HUBSPOT_CONFIG_ERROR_TYPES.UNKNOWN;
340
+ if (error instanceof Error && 'code' in error) {
341
+ if (error.code === 'ENOENT') {
342
+ message = (0, lang_1.i18n)('config.utils.handleConfigFileSystemError.configNotFoundError', { path });
343
+ type = config_1.HUBSPOT_CONFIG_ERROR_TYPES.CONFIG_NOT_FOUND;
344
+ }
345
+ else if (error.code === 'EACCES') {
346
+ message = (0, lang_1.i18n)('config.utils.handleConfigFileSystemError.insufficientPermissionsError', { path });
347
+ type = config_1.HUBSPOT_CONFIG_ERROR_TYPES.INSUFFICIENT_PERMISSIONS;
348
+ }
349
+ }
350
+ return { message, type };
351
+ }
352
+ exports.handleConfigFileSystemError = handleConfigFileSystemError;
@@ -18,6 +18,7 @@ export declare const ALLOW_AUTO_UPDATES = "allowAutoUpdates";
18
18
  export declare const DEFAULT_ACCOUNT = "defaultAccount";
19
19
  export declare const DEFAULT_PORTAL = "defaultPortal";
20
20
  export declare const MIN_HTTP_TIMEOUT = 3000;
21
+ export declare const MCP_TOTAL_TOOL_CALLS_STATE = "mcpTotalToolCalls";
21
22
  export declare const HUBSPOT_ACCOUNT_TYPES: {
22
23
  readonly DEVELOPMENT_SANDBOX: "DEVELOPMENT_SANDBOX";
23
24
  readonly DEVELOPER_TEST: "DEVELOPER_TEST";
@@ -56,3 +57,19 @@ export declare const ACCOUNT_IDENTIFIERS: {
56
57
  readonly ACCOUNT_ID: "accountId";
57
58
  readonly NAME: "name";
58
59
  };
60
+ export declare const HUBSPOT_CONFIG_ERROR_TYPES: {
61
+ readonly CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND";
62
+ readonly INSUFFICIENT_PERMISSIONS: "INSUFFICIENT_PERMISSIONS";
63
+ readonly ACCOUNT_NOT_FOUND: "ACCOUNT_NOT_FOUND";
64
+ readonly NO_DEFAULT_ACCOUNT: "NO_DEFAULT_ACCOUNT";
65
+ readonly INVALID_ENVIRONMENT_VARIABLES: "ENVIRONMENT_VARIABLES";
66
+ readonly YAML_PARSING: "YAML_PARSING";
67
+ readonly INVALID_ACCOUNT: "INVALID_ACCOUNT";
68
+ readonly INVALID_FIELD: "INVALID_FIELD";
69
+ readonly UNKNOWN: "UNKNOWN";
70
+ };
71
+ export declare const HUBSPOT_CONFIG_OPERATIONS: {
72
+ readonly READ: "READ";
73
+ readonly WRITE: "WRITE";
74
+ readonly DELETE: "DELETE";
75
+ };
@@ -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.ACCOUNT_IDENTIFIERS = exports.ENVIRONMENT_VARIABLES = exports.CONFIG_FLAGS = exports.HUBSPOT_ACCOUNT_TYPE_STRINGS = exports.HUBSPOT_ACCOUNT_TYPES = exports.MIN_HTTP_TIMEOUT = exports.DEFAULT_PORTAL = exports.DEFAULT_ACCOUNT = exports.ALLOW_AUTO_UPDATES = exports.AUTO_OPEN_BROWSER = exports.ALLOW_USAGE_TRACKING = exports.HTTP_USE_LOCALHOST = exports.ENV = exports.HTTP_TIMEOUT = exports.DEFAULT_CMS_PUBLISH_MODE = exports.DEFAULT_ACCOUNT_OVERRIDE_ERROR_ACCOUNT_NOT_FOUND = exports.DEFAULT_ACCOUNT_OVERRIDE_ERROR_INVALID_ID = exports.DEFAULT_ACCOUNT_OVERRIDE_FILE_NAME = exports.STATE_FILE_PATH = exports.GLOBAL_CONFIG_PATH = exports.HUBSPOT_STATE_FILE = exports.HUBSPOT_CONFIGURATION_FILE = exports.HUBSPOT_CONFIGURATION_FOLDER = exports.ARCHIVED_HUBSPOT_CONFIG_YAML_FILE_NAME = exports.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME = void 0;
6
+ exports.HUBSPOT_CONFIG_OPERATIONS = exports.HUBSPOT_CONFIG_ERROR_TYPES = exports.ACCOUNT_IDENTIFIERS = exports.ENVIRONMENT_VARIABLES = exports.CONFIG_FLAGS = exports.HUBSPOT_ACCOUNT_TYPE_STRINGS = exports.HUBSPOT_ACCOUNT_TYPES = exports.MCP_TOTAL_TOOL_CALLS_STATE = exports.MIN_HTTP_TIMEOUT = exports.DEFAULT_PORTAL = exports.DEFAULT_ACCOUNT = exports.ALLOW_AUTO_UPDATES = exports.AUTO_OPEN_BROWSER = exports.ALLOW_USAGE_TRACKING = exports.HTTP_USE_LOCALHOST = exports.ENV = exports.HTTP_TIMEOUT = exports.DEFAULT_CMS_PUBLISH_MODE = exports.DEFAULT_ACCOUNT_OVERRIDE_ERROR_ACCOUNT_NOT_FOUND = exports.DEFAULT_ACCOUNT_OVERRIDE_ERROR_INVALID_ID = exports.DEFAULT_ACCOUNT_OVERRIDE_FILE_NAME = exports.STATE_FILE_PATH = exports.GLOBAL_CONFIG_PATH = exports.HUBSPOT_STATE_FILE = exports.HUBSPOT_CONFIGURATION_FILE = exports.HUBSPOT_CONFIGURATION_FOLDER = exports.ARCHIVED_HUBSPOT_CONFIG_YAML_FILE_NAME = exports.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME = void 0;
7
7
  const lang_1 = require("../utils/lang");
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const os_1 = __importDefault(require("os"));
@@ -27,6 +27,7 @@ exports.ALLOW_AUTO_UPDATES = 'allowAutoUpdates';
27
27
  exports.DEFAULT_ACCOUNT = 'defaultAccount';
28
28
  exports.DEFAULT_PORTAL = 'defaultPortal';
29
29
  exports.MIN_HTTP_TIMEOUT = 3000;
30
+ exports.MCP_TOTAL_TOOL_CALLS_STATE = 'mcpTotalToolCalls';
30
31
  exports.HUBSPOT_ACCOUNT_TYPES = {
31
32
  DEVELOPMENT_SANDBOX: 'DEVELOPMENT_SANDBOX',
32
33
  DEVELOPER_TEST: 'DEVELOPER_TEST',
@@ -65,3 +66,19 @@ exports.ACCOUNT_IDENTIFIERS = {
65
66
  ACCOUNT_ID: 'accountId',
66
67
  NAME: 'name',
67
68
  };
69
+ exports.HUBSPOT_CONFIG_ERROR_TYPES = {
70
+ CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',
71
+ INSUFFICIENT_PERMISSIONS: 'INSUFFICIENT_PERMISSIONS',
72
+ ACCOUNT_NOT_FOUND: 'ACCOUNT_NOT_FOUND',
73
+ NO_DEFAULT_ACCOUNT: 'NO_DEFAULT_ACCOUNT',
74
+ INVALID_ENVIRONMENT_VARIABLES: 'ENVIRONMENT_VARIABLES',
75
+ YAML_PARSING: 'YAML_PARSING',
76
+ INVALID_ACCOUNT: 'INVALID_ACCOUNT',
77
+ INVALID_FIELD: 'INVALID_FIELD',
78
+ UNKNOWN: 'UNKNOWN',
79
+ };
80
+ exports.HUBSPOT_CONFIG_OPERATIONS = {
81
+ READ: 'READ',
82
+ WRITE: 'WRITE',
83
+ DELETE: 'DELETE',
84
+ };
package/errors/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { HubSpotHttpError } from '../models/HubSpotHttpError';
2
2
  import { BaseError } from '../types/Error';
3
3
  import { FileSystemError } from '../models/FileSystemError';
4
+ import { HubSpotConfigError } from '../models/HubSpotConfigError';
4
5
  export declare function isSpecifiedError(err: unknown, { statusCode, category, subCategory, errorType, code, }: {
5
6
  statusCode?: number;
6
7
  category?: string;
@@ -17,3 +18,4 @@ export declare function isHubSpotHttpError(error?: unknown): error is HubSpotHtt
17
18
  export declare function isGithubRateLimitError(err: unknown): boolean;
18
19
  export declare function isSystemError(err: unknown): err is BaseError;
19
20
  export declare function isFileSystemError(err: unknown): err is FileSystemError;
21
+ export declare function isHubSpotConfigError(err: unknown): err is HubSpotConfigError;
package/errors/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isFileSystemError = exports.isSystemError = exports.isGithubRateLimitError = exports.isHubSpotHttpError = exports.isValidationError = exports.isAuthError = exports.isTimeoutError = exports.isGatingError = exports.isMissingScopeError = exports.isSpecifiedError = void 0;
3
+ exports.isHubSpotConfigError = exports.isFileSystemError = exports.isSystemError = exports.isGithubRateLimitError = exports.isHubSpotHttpError = exports.isValidationError = exports.isAuthError = exports.isTimeoutError = exports.isGatingError = exports.isMissingScopeError = exports.isSpecifiedError = void 0;
4
4
  const HubSpotHttpError_1 = require("../models/HubSpotHttpError");
5
5
  const FileSystemError_1 = require("../models/FileSystemError");
6
+ const HubSpotConfigError_1 = require("../models/HubSpotConfigError");
6
7
  function isSpecifiedError(err, { statusCode, category, subCategory, errorType, code, }) {
7
8
  if (!isHubSpotHttpError(err)) {
8
9
  return false;
@@ -70,3 +71,7 @@ function isFileSystemError(err) {
70
71
  return err instanceof FileSystemError_1.FileSystemError;
71
72
  }
72
73
  exports.isFileSystemError = isFileSystemError;
74
+ function isHubSpotConfigError(err) {
75
+ return err instanceof HubSpotConfigError_1.HubSpotConfigError;
76
+ }
77
+ exports.isHubSpotConfigError = isHubSpotConfigError;
package/http/index.js CHANGED
@@ -42,22 +42,29 @@ const HubSpotHttpError_1 = require("../models/HubSpotHttpError");
42
42
  const auth_1 = require("../constants/auth");
43
43
  const localDevAuth_1 = require("../api/localDevAuth");
44
44
  const util = __importStar(require("util"));
45
+ const trackUsage_1 = require("../lib/trackUsage");
45
46
  const i18nKey = 'http.index';
47
+ const IGNORE_URLS_NETWORK_DEBUG = [
48
+ localDevAuth_1.LOCALDEVAUTH_ACCESS_TOKEN_PATH,
49
+ trackUsage_1.CMS_CLI_USAGE_PATH,
50
+ trackUsage_1.VSCODE_USAGE_PATH,
51
+ ];
46
52
  function logRequest(response) {
47
53
  try {
48
- if (process.env.HUBSPOT_NETWORK_LOGGING) {
49
- if (response.config.url === localDevAuth_1.LOCALDEVAUTH_ACCESS_TOKEN_PATH) {
50
- // Don't log access tokens
51
- return;
52
- }
53
- logger_1.logger.debug(util.inspect({
54
- method: response.config.method,
55
- baseURL: response.config.baseURL,
56
- url: response.config.url,
57
- data: response.data,
58
- status: response.status,
59
- }, false, null, true));
54
+ if (!process.env.HUBSPOT_NETWORK_LOGGING) {
55
+ return;
56
+ }
57
+ if (response?.config?.url &&
58
+ IGNORE_URLS_NETWORK_DEBUG.includes(response.config.url)) {
59
+ return;
60
60
  }
61
+ logger_1.logger.debug(util.inspect({
62
+ method: response.config.method,
63
+ baseURL: response.config.baseURL,
64
+ url: response.config.url,
65
+ data: response.data,
66
+ status: response.status,
67
+ }, false, null, true));
61
68
  }
62
69
  catch (error) {
63
70
  // Ignore any errors that occur while logging the response
package/lang/en.json CHANGED
@@ -244,9 +244,13 @@
244
244
  },
245
245
  "config": {
246
246
  "getDefaultConfigFilePath": {
247
- "error": "Error getting config file path: no config file found"
247
+ "error": "Attempted to get config file path, but no config file was found."
248
+ },
249
+ "getConfig": {
250
+ "reading": "Reading config from {{ path }}",
251
+ "error": "No config file found.",
252
+ "errorWithPath": "No config file found at {{ path }}."
248
253
  },
249
- "getConfig": "Reading config from {{ path }}",
250
254
  "isConfigValid": {
251
255
  "missingAccounts": "Invalid config: no accounts found",
252
256
  "duplicateAccountIds": "Invalid config: multiple accounts with accountId: {{ accountId }}",
@@ -254,40 +258,47 @@
254
258
  "invalidAccountName": "Invalid config: account name {{ accountName }} contains spaces"
255
259
  },
256
260
  "getConfigAccountById": {
257
- "error": "Error getting config account: no account with id {{ accountId }} exists in config"
261
+ "error": "No account with id {{ accountId }} exists in config"
258
262
  },
259
263
  "getConfigAccountByName": {
260
- "error": "Error getting config account: no account with name {{ accountName }} exists in config"
264
+ "error": "No account with name {{ accountName }} exists in config"
261
265
  },
262
266
  "getConfigDefaultAccount": {
263
- "fieldMissingError": "Error getting config default account: no default account field found in config",
264
- "accountMissingError": "Error getting config default account: default account is set to {{ defaultAccount }} but no account with that id exists in config"
267
+ "fieldMissingError": "Attempted to get default account, but no default account was found in config",
268
+ "accountMissingError": "Default account is set to {{ defaultAccount }}, but no account with that id exists in config"
265
269
  },
266
270
  "addConfigAccount": {
267
- "invalidAccount": "Error adding config account: account is invalid",
268
- "duplicateAccount": "Error adding config account: account with id {{ accountId }} already exists in config"
271
+ "invalidAccount": "Attempting to add account, but account is invalid",
272
+ "duplicateAccount": "Attempting to add account, but account with id {{ accountId }} already exists in config"
269
273
  },
270
274
  "updateConfigAccount": {
271
- "invalidAccount": "Error updating config account: account is invalid",
272
- "accountNotFound": "Error updating config account: account with id {{ accountId }} not found in config"
275
+ "invalidAccount": "Attempting to update account {{ name }}, but account is invalid",
276
+ "accountNotFound": "Attempting to update account with id {{ id }}, but that account was not found in config"
273
277
  },
274
278
  "setConfigAccountAsDefault": {
275
- "accountNotFound": "Error setting config default account: account with id {{ accountId }} not found in config"
279
+ "accountNotFound": "Attempted to set account with id {{ accountId }} as default, but that account was not found in config"
276
280
  },
277
281
  "renameConfigAccount": {
278
- "accountNotFound": "Error renaming config account: account with name {{ currentName }} not found in config",
279
- "duplicateAccount": "Error renaming config account: account with name {{ newName}} already exists in config"
282
+ "accountNotFound": "Attempted to rename account with name {{ currentName }}, but that account was not found in config",
283
+ "duplicateAccount": "Attempted to rename account {{ currentName }} to {{ newName }}, but an account with that name already exists in config"
280
284
  },
281
285
  "removeAccountFromConfig": {
282
- "accountNotFound": "Error removing config account: account with id {{ accountId }} not found in config"
286
+ "accountNotFound": "Attempted to remove account with id {{ accountId }}, but that account was not found in config"
283
287
  },
284
288
  "updateHttpTimeout": {
285
- "invalidTimeout": "Error updating config http timeout: timeout must be greater than {{ minTimeout }}"
289
+ "invalidTimeout": "HTTP timeout must be greater than {{ minTimeout }}. Received {{ timeout }}"
286
290
  },
287
291
  "updateDefaultCmsPublishMode": {
288
292
  "invalidCmsPublishMode": "Error updating config default CMS publish mode: CMS publish can only be set to 'draft' or 'publish'"
289
293
  },
294
+ "getConfigAccountEnvironment": {
295
+ "accountNotFound": "Attempted to get environment for account with identifier {{ identifier }}, but that account was not found in config"
296
+ },
290
297
  "utils": {
298
+ "handleConfigFileSystemError": {
299
+ "configNotFoundError": "No config file found at {{ path }}.",
300
+ "insufficientPermissionsError": "Insufficient permissions to access config file at {{ path }}"
301
+ },
291
302
  "isConfigAccountValid": {
292
303
  "missingAccount": "Invalid config: at least one account in config is missing data",
293
304
  "missingAuthType": "Invalid config: account {{ accountId }} has no authType",
@@ -297,14 +308,14 @@
297
308
  "missingPersonalAccessKey": "Invalid config: account {{ accountId }} has authType of personalAccessKey but is missing the personalAccessKey field"
298
309
  },
299
310
  "getConfigPathEnvironmentVariables": {
300
- "invalidEnvironmentVariables": "Error loading config: USE_ENVIRONMENT_HUBSPOT_CONFIG and HUBSPOT_CONFIG_PATH cannot both be set simultaneously"
311
+ "invalidEnvironmentVariables": "USE_ENVIRONMENT_HUBSPOT_CONFIG and HUBSPOT_CONFIG_PATH cannot both be set simultaneously"
301
312
  },
302
313
  "parseConfig": {
303
- "error": "An error occurred parsing the config file."
314
+ "error": "File could not be parsed. Confirm that your config file {{ configPath }} is valid YAML."
304
315
  },
305
316
  "buildConfigFromEnvironment": {
306
- "missingAccountId": "Error loading config from environment: HUBSPOT_ACCOUNT_ID not set",
307
- "invalidAuthType": "Error loading config from environment: auth is invalid. Use HUBSPOT_CLIENT_ID, HUBSPOT_CLIENT_SECRET, and HUBSPOT_REFRESH_TOKEN to authenticate with Oauth2, PERSONAL_ACCESS_KEY to authenticate with Personal Access Key, or API_KEY to authenticate with API Key."
317
+ "missingAccountId": "HUBSPOT_ACCOUNT_ID is required, but not currently set",
318
+ "invalidAuthType": "Auth type is invalid. Use HUBSPOT_CLIENT_ID, HUBSPOT_CLIENT_SECRET, and HUBSPOT_REFRESH_TOKEN to authenticate with Oauth2, PERSONAL_ACCESS_KEY to authenticate with Personal Access Key, or API_KEY to authenticate with API Key."
308
319
  }
309
320
  },
310
321
  "defaultAccountOverride": {
@@ -313,6 +324,12 @@
313
324
  "readFileError": "Error reading account override file."
314
325
  }
315
326
  },
327
+ "updateAllowUsageTracking": {
328
+ "invalidInput": "Unable to update allowUsageTracking. The value {{ isAllowed }} is invalid. The value must be a boolean."
329
+ },
330
+ "updateAllowAutoUpdates": {
331
+ "invalidInput": "Unable to update allowAutoUpdates. The value {{ isEnabled }} is invalid. The value must be a boolean."
332
+ },
316
333
  "updateAutoOpenBrowser": {
317
334
  "invalidInput": "Unable to update autoOpenBrowser. The value {{ isEnabled }} is invalid. The value must be a boolean."
318
335
  },
@@ -334,6 +351,9 @@
334
351
  }
335
352
  },
336
353
  "getCurrentState": {
354
+ "debug": {
355
+ "emptyStateFile": "State file is empty, using default state"
356
+ },
337
357
  "errors": {
338
358
  "errorReading": "Error reading CLI state, using defaults: {{ error }}"
339
359
  }
@@ -367,6 +387,9 @@
367
387
  "missingRefreshToken": "The account {{ accountId }} has not been authenticated with Oauth2",
368
388
  "auth": "Error while retrieving new token: {{ token }}"
369
389
  }
390
+ },
391
+ "HubSpotConfigError": {
392
+ "baseMessage": "An error occurred while {{ operation }} your HubSpot config {{ configType }}{{ message }}"
370
393
  }
371
394
  },
372
395
  "utils": {
@@ -121,10 +121,8 @@ 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 = name
125
- ? (0, config_1.getConfigAccountByName)(name)
126
- : (0, config_1.getConfigDefaultAccount)();
127
- const accountEnv = env || account.env;
124
+ const account = (0, config_1.getConfigAccountIfExists)(portalId);
125
+ const accountEnv = env || account?.env || environments_1.ENVIRONMENTS.PROD;
128
126
  let parentAccountId;
129
127
  try {
130
128
  if (accountType === config_2.HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX ||
@@ -161,15 +159,21 @@ async function updateConfigWithAccessToken(token, personalAccessKey, env, name,
161
159
  accountId: portalId,
162
160
  accountType,
163
161
  personalAccessKey,
164
- name: name || account.name,
162
+ name: name || account?.name || token.hubName,
165
163
  authType: auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value,
166
164
  auth: { tokenInfo: { accessToken, expiresAt } },
167
165
  parentAccountId,
168
166
  env: accountEnv,
169
167
  };
170
- (0, config_1.updateConfigAccount)(updatedAccount);
171
- if (makeDefault && name) {
172
- (0, config_1.setConfigAccountAsDefault)(name);
168
+ // Add new account if it doesn't exist, otherwise update existing account
169
+ if (account) {
170
+ (0, config_1.updateConfigAccount)(updatedAccount);
171
+ }
172
+ else {
173
+ (0, config_1.addConfigAccount)(updatedAccount);
174
+ }
175
+ if (makeDefault) {
176
+ (0, config_1.setConfigAccountAsDefault)(updatedAccount.accountId);
173
177
  }
174
178
  return updatedAccount;
175
179
  }
@@ -7,11 +7,10 @@ exports.portManagerHasActiveServers = exports.deleteServerInstance = exports.get
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const PortManagerServer_1 = require("../utils/PortManagerServer");
9
9
  const ports_1 = require("../constants/ports");
10
- const detectPort_1 = require("../utils/detectPort");
11
10
  const logger_1 = require("./logger");
12
11
  exports.BASE_URL = `http://localhost:${ports_1.PORT_MANAGER_SERVER_PORT}`;
13
12
  async function isPortManagerPortAvailable() {
14
- return ((await (0, detectPort_1.detectPort)(ports_1.PORT_MANAGER_SERVER_PORT)) === ports_1.PORT_MANAGER_SERVER_PORT);
13
+ return PortManagerServer_1.PortManagerServer.portAvailable();
15
14
  }
16
15
  exports.isPortManagerPortAvailable = isPortManagerPortAvailable;
17
16
  async function isPortManagerServerRunning() {
@@ -1 +1,3 @@
1
+ export declare const CMS_CLI_USAGE_PATH: string;
2
+ export declare const VSCODE_USAGE_PATH: string;
1
3
  export declare function trackUsage(eventName: string, eventClass: string, meta?: {}, accountId?: number): Promise<void>;
package/lib/trackUsage.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.trackUsage = void 0;
6
+ exports.trackUsage = exports.VSCODE_USAGE_PATH = exports.CMS_CLI_USAGE_PATH = 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");
@@ -13,6 +13,8 @@ const fileMapper_1 = require("../api/fileMapper");
13
13
  const lang_1 = require("../utils/lang");
14
14
  const environment_1 = require("./environment");
15
15
  const i18nKey = 'lib.trackUsage';
16
+ exports.CMS_CLI_USAGE_PATH = `${fileMapper_1.FILE_MAPPER_API_PATH}/cms-cli-usage`;
17
+ exports.VSCODE_USAGE_PATH = `${fileMapper_1.FILE_MAPPER_API_PATH}/vscode-extension-usage`;
16
18
  async function trackUsage(eventName, eventClass, meta = {}, accountId) {
17
19
  const usageEvent = {
18
20
  accountId,
@@ -24,18 +26,17 @@ async function trackUsage(eventName, eventClass, meta = {}, accountId) {
24
26
  VSCODE_EXTENSION_INTERACTION: 'vscode-extension-interaction',
25
27
  CLI_INTERACTION: 'cli-interaction',
26
28
  };
27
- let analyticsEndpoint;
29
+ let path = fileMapper_1.FILE_MAPPER_API_PATH;
28
30
  switch (eventName) {
29
31
  case EVENT_TYPES.CLI_INTERACTION:
30
- analyticsEndpoint = 'cms-cli-usage';
32
+ path = exports.CMS_CLI_USAGE_PATH;
31
33
  break;
32
34
  case EVENT_TYPES.VSCODE_EXTENSION_INTERACTION:
33
- analyticsEndpoint = 'vscode-extension-usage';
35
+ path = exports.VSCODE_USAGE_PATH;
34
36
  break;
35
37
  default:
36
38
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.invalidEvent`, { eventName }));
37
39
  }
38
- const path = `${fileMapper_1.FILE_MAPPER_API_PATH}/${analyticsEndpoint}`;
39
40
  const account = accountId && (0, config_1.getConfigAccountById)(accountId);
40
41
  if (account && account.authType === 'personalaccesskey') {
41
42
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.sendingEventAuthenticated`));
@@ -0,0 +1,6 @@
1
+ import { HubSpotConfigErrorType, HubSpotConfigOperation } from '../types/Config';
2
+ export declare class HubSpotConfigError extends Error {
3
+ type: HubSpotConfigErrorType;
4
+ operation: HubSpotConfigOperation;
5
+ constructor(message: string | undefined, type: HubSpotConfigErrorType, operation: HubSpotConfigOperation, options?: ErrorOptions);
6
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HubSpotConfigError = void 0;
4
+ const config_1 = require("../constants/config");
5
+ const lang_1 = require("../utils/lang");
6
+ const NAME = 'HubSpotConfigError';
7
+ const OPERATION_TEXT = {
8
+ [config_1.HUBSPOT_CONFIG_OPERATIONS.READ]: 'reading',
9
+ [config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE]: 'writing to',
10
+ [config_1.HUBSPOT_CONFIG_OPERATIONS.DELETE]: 'deleting',
11
+ };
12
+ function isEnvironmentError(type) {
13
+ return type === config_1.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ENVIRONMENT_VARIABLES;
14
+ }
15
+ class HubSpotConfigError extends Error {
16
+ type;
17
+ operation;
18
+ constructor(message, type, operation, options) {
19
+ const configType = isEnvironmentError(type)
20
+ ? 'environment variables'
21
+ : 'file';
22
+ const operationText = OPERATION_TEXT[operation];
23
+ const withBaseMessage = (0, lang_1.i18n)('models.HubSpotConfigError.baseMessage', {
24
+ configType,
25
+ message: message ? `: ${message}` : '',
26
+ operation: operationText,
27
+ });
28
+ super(withBaseMessage, options);
29
+ this.name = NAME;
30
+ this.type = type;
31
+ this.operation = operation;
32
+ }
33
+ }
34
+ exports.HubSpotConfigError = HubSpotConfigError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/local-dev-lib",
3
- "version": "0.5.0-experimental.0",
3
+ "version": "0.5.0-experimental.10",
4
4
  "description": "Provides library functionality for HubSpot local development tooling, including the HubSpot CLI",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,7 +21,6 @@
21
21
  "license": "Apache-2.0",
22
22
  "devDependencies": {
23
23
  "@hubspot/npm-scripts": "0.0.4",
24
- "@inquirer/prompts": "^7.0.1",
25
24
  "@types/content-disposition": "^0.5.5",
26
25
  "@types/cors": "^2.8.15",
27
26
  "@types/debounce": "^1.2.1",
package/types/Config.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CONFIG_FLAGS } from '../constants/config';
1
+ import { CONFIG_FLAGS, HUBSPOT_CONFIG_ERROR_TYPES, HUBSPOT_CONFIG_OPERATIONS } from '../constants/config';
2
2
  import { ENVIRONMENTS } from '../constants/environments';
3
3
  import { DeprecatedHubSpotConfigAccountFields, HubSpotConfigAccount } from './Accounts';
4
4
  import { CmsPublishMode } from './Files';
@@ -29,6 +29,8 @@ export type GitInclusionResult = {
29
29
  gitignoreFiles: Array<string>;
30
30
  };
31
31
  export type ConfigFlag = ValueOf<typeof CONFIG_FLAGS>;
32
- export type CLIState = {
32
+ export type HubSpotState = {
33
33
  mcpTotalToolCalls: number;
34
34
  };
35
+ export type HubSpotConfigErrorType = ValueOf<typeof HUBSPOT_CONFIG_ERROR_TYPES>;
36
+ export type HubSpotConfigOperation = ValueOf<typeof HUBSPOT_CONFIG_OPERATIONS>;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
- import { Express, Request, Response } from 'express';
2
+ import { Express } from 'express';
3
3
  import { Server } from 'http';
4
- import { RequestPortsData, ServerPortMap } from '../types/PortManager';
4
+ import { ServerPortMap } from '../types/PortManager';
5
5
  export declare const HEALTH_CHECK_PATH = "/port-manager-health-check";
6
6
  export declare const SERVICE_HEALTHY = "OK";
7
7
  declare class _PortManagerServer {
@@ -10,19 +10,18 @@ declare class _PortManagerServer {
10
10
  serverPortMap: ServerPortMap;
11
11
  constructor();
12
12
  init(): Promise<void>;
13
- reset(): void;
14
- listen(): Promise<Server>;
15
- setupRoutes(): void;
16
- setPort(instanceId: string, port: number): void;
17
- deletePort(instanceId: string): void;
18
- send404(res: Response, instanceId: string): void;
19
- getServers: (req: Request, res: Response) => Promise<void>;
20
- getServerPortByInstanceId: (req: Request, res: Response) => void;
21
- assignPortsToServers: (req: Request<never, never, {
22
- portData: Array<RequestPortsData>;
23
- }>, res: Response) => Promise<void>;
24
- deleteServerInstance: (req: Request, res: Response) => void;
25
- closeServer: (req: Request, res: Response) => void;
13
+ private reset;
14
+ portAvailable(): Promise<boolean>;
15
+ private listen;
16
+ private setupRoutes;
17
+ private setPort;
18
+ private deletePort;
19
+ private send404;
20
+ private getServers;
21
+ private getServerPortByInstanceId;
22
+ private assignPortsToServers;
23
+ private deleteServerInstance;
24
+ private closeServer;
26
25
  }
27
26
  export declare const PortManagerServer: _PortManagerServer;
28
27
  export {};
@@ -8,7 +8,6 @@ const express_1 = __importDefault(require("express"));
8
8
  const cors_1 = __importDefault(require("cors"));
9
9
  const detectPort_1 = require("./detectPort");
10
10
  const ports_1 = require("../constants/ports");
11
- const errors_1 = require("../errors");
12
11
  const logger_1 = require("../lib/logger");
13
12
  const lang_1 = require("./lang");
14
13
  const i18nKey = 'utils.PortManagerServer';
@@ -22,6 +21,11 @@ class _PortManagerServer {
22
21
  this.serverPortMap = {};
23
22
  }
24
23
  async init() {
24
+ if (!(await this.portAvailable())) {
25
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.portInUse`, {
26
+ port: ports_1.PORT_MANAGER_SERVER_PORT,
27
+ }));
28
+ }
25
29
  if (this.app) {
26
30
  throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.duplicateInstance`));
27
31
  }
@@ -29,24 +33,17 @@ class _PortManagerServer {
29
33
  this.app.use(express_1.default.json());
30
34
  this.app.use((0, cors_1.default)());
31
35
  this.setupRoutes();
32
- try {
33
- this.server = await this.listen();
34
- logger_1.logger.debug(this.server);
35
- }
36
- catch (e) {
37
- if ((0, errors_1.isSystemError)(e) && e.code === 'EADDRINUSE') {
38
- throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.portInUse`, {
39
- port: ports_1.PORT_MANAGER_SERVER_PORT,
40
- }), { cause: e });
41
- }
42
- throw e;
43
- }
36
+ this.server = await this.listen();
37
+ logger_1.logger.debug(this.server);
44
38
  }
45
39
  reset() {
46
40
  this.app = undefined;
47
41
  this.server = undefined;
48
42
  this.serverPortMap = {};
49
43
  }
44
+ async portAvailable() {
45
+ return ((await (0, detectPort_1.detectPort)(ports_1.PORT_MANAGER_SERVER_PORT)) === ports_1.PORT_MANAGER_SERVER_PORT);
46
+ }
50
47
  listen() {
51
48
  return new Promise((resolve, reject) => {
52
49
  const server = this.app.listen(ports_1.PORT_MANAGER_SERVER_PORT, () => {