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

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.
Files changed (47) hide show
  1. package/config/defaultAccountOverride.d.ts +2 -0
  2. package/config/defaultAccountOverride.js +57 -0
  3. package/config/index.d.ts +27 -44
  4. package/config/index.js +300 -275
  5. package/config/migrate.d.ts +11 -16
  6. package/config/migrate.js +79 -161
  7. package/config/state.d.ts +3 -3
  8. package/config/state.js +12 -28
  9. package/config/utils.d.ts +74 -0
  10. package/config/utils.js +327 -0
  11. package/constants/config.d.ts +37 -0
  12. package/constants/config.js +38 -1
  13. package/constants/environments.d.ts +0 -11
  14. package/constants/environments.js +1 -12
  15. package/errors/index.d.ts +2 -0
  16. package/errors/index.js +6 -1
  17. package/http/getAxiosConfig.js +7 -1
  18. package/http/index.js +23 -19
  19. package/lang/en.json +83 -65
  20. package/lib/cms/themes.js +3 -1
  21. package/lib/environment.d.ts +1 -1
  22. package/lib/oauth.d.ts +2 -2
  23. package/lib/oauth.js +8 -16
  24. package/lib/personalAccessKey.d.ts +2 -2
  25. package/lib/personalAccessKey.js +39 -30
  26. package/lib/trackUsage.js +6 -3
  27. package/models/HubSpotConfigError.d.ts +6 -0
  28. package/models/HubSpotConfigError.js +29 -0
  29. package/models/OAuth2Manager.d.ts +3 -4
  30. package/models/OAuth2Manager.js +20 -29
  31. package/package.json +2 -2
  32. package/types/Accounts.d.ts +20 -109
  33. package/types/Config.d.ts +14 -27
  34. package/config/CLIConfiguration.d.ts +0 -72
  35. package/config/CLIConfiguration.js +0 -551
  36. package/config/configFile.d.ts +0 -21
  37. package/config/configFile.js +0 -100
  38. package/config/configUtils.d.ts +0 -5
  39. package/config/configUtils.js +0 -87
  40. package/config/config_DEPRECATED.d.ts +0 -87
  41. package/config/config_DEPRECATED.js +0 -738
  42. package/config/environment.d.ts +0 -2
  43. package/config/environment.js +0 -60
  44. package/config/getAccountIdentifier.d.ts +0 -2
  45. package/config/getAccountIdentifier.js +0 -15
  46. package/utils/accounts.d.ts +0 -4
  47. package/utils/accounts.js +0 -28
package/lang/en.json CHANGED
@@ -75,7 +75,8 @@
75
75
  "personalAccessKey": {
76
76
  "errors": {
77
77
  "accountNotFound": "Account with id {{ accountId }} does not exist.",
78
- "invalidPersonalAccessKey": "Error while retrieving new access token: {{ errorMessage }}"
78
+ "invalidPersonalAccessKey": "Error while retrieving new access token: {{ errorMessage }}",
79
+ "invalidAuthType": "Error fetching access token: account {{ accountId }} uses an auth type other than personalaccesskey"
79
80
  }
80
81
  },
81
82
  "crm": {
@@ -242,73 +243,89 @@
242
243
  }
243
244
  },
244
245
  "config": {
245
- "cliConfiguration": {
246
- "errors": {
247
- "noConfigLoaded": "No config loaded."
248
- },
249
- "load": {
250
- "configFromEnv": "Loaded config from environment variables for {{ accountId }}",
251
- "configFromFile": "Loaded config from configuration file.",
252
- "empty": "The config file was empty. Initializing an empty config."
253
- },
254
- "validate": {
255
- "noConfig": "Validation failed: No config was found.",
256
- "noConfigAccounts": "Validation failed: config.accounts[] is not defined.",
257
- "emptyAccountConfig": "Validation failed: config.accounts[] has an empty entry.",
258
- "noAccountId": "Validation failed: config.accounts[] has an entry missing accountId.",
259
- "duplicateAccountIds": "Validation failed: config.accounts[] has multiple entries with {{ accountId }}.",
260
- "duplicateAccountNames": "Validation failed: config.accounts[] has multiple entries with {{ accountName }}.",
261
- "nameContainsSpaces": "Validation failed: config.name {{ accountName }} cannot contain spaces."
246
+ "getDefaultConfigFilePath": {
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 }}."
253
+ },
254
+ "isConfigValid": {
255
+ "missingAccounts": "Invalid config: no accounts found",
256
+ "duplicateAccountIds": "Invalid config: multiple accounts with accountId: {{ accountId }}",
257
+ "duplicateAccountNames": "Invalid config: multiple accounts with name: {{ accountName }}",
258
+ "invalidAccountName": "Invalid config: account name {{ accountName }} contains spaces"
259
+ },
260
+ "getConfigAccountById": {
261
+ "error": "No account with id {{ accountId }} exists in config"
262
+ },
263
+ "getConfigAccountByName": {
264
+ "error": "No account with name {{ accountName }} exists in config"
265
+ },
266
+ "getConfigDefaultAccount": {
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"
269
+ },
270
+ "addConfigAccount": {
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"
273
+ },
274
+ "updateConfigAccount": {
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"
277
+ },
278
+ "setConfigAccountAsDefault": {
279
+ "accountNotFound": "Attempted to set account with id {{ accountId }} as default, but that account was not found in config"
280
+ },
281
+ "renameConfigAccount": {
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"
284
+ },
285
+ "removeAccountFromConfig": {
286
+ "accountNotFound": "Attempted to remove account with id {{ accountId }}, but that account was not found in config"
287
+ },
288
+ "updateHttpTimeout": {
289
+ "invalidTimeout": "HTTP timeout must be greater than {{ minTimeout }}. Received {{ timeout }}"
290
+ },
291
+ "updateDefaultCmsPublishMode": {
292
+ "invalidCmsPublishMode": "Error updating config default CMS publish mode: CMS publish can only be set to 'draft' or 'publish'"
293
+ },
294
+ "utils": {
295
+ "isConfigAccountValid": {
296
+ "missingAccount": "Invalid config: at least one account in config is missing data",
297
+ "missingAuthType": "Invalid config: account {{ accountId }} has no authType",
298
+ "missingAccountId": "Invalid config: at least one account in config is missing accountId",
299
+ "missingApiKey": "Invalid config: account {{ accountId }} has authType of apikey but is missing the apiKey field",
300
+ "missingAuth": "Invalid config: account {{ accountId }} has authtype of oauth2 but is missing auth data",
301
+ "missingPersonalAccessKey": "Invalid config: account {{ accountId }} has authType of personalAccessKey but is missing the personalAccessKey field"
262
302
  },
263
- "updateAccount": {
264
- "noConfigToUpdate": "No config to update.",
265
- "updating": "Updating account config for {{ accountId }}",
266
- "addingConfigEntry": "Adding account config entry for {{ accountId }}",
267
- "errors": {
268
- "accountIdRequired": "An accountId is required to update the config"
269
- }
303
+ "getConfigPathEnvironmentVariables": {
304
+ "invalidEnvironmentVariables": "USE_ENVIRONMENT_HUBSPOT_CONFIG and HUBSPOT_CONFIG_PATH cannot both be set simultaneously"
270
305
  },
271
- "updateDefaultAccount": {
272
- "errors": {
273
- "invalidInput": "A 'defaultAccount' with value of number or string is required to update the config."
274
- }
306
+ "parseConfig": {
307
+ "error": "File could not be parsed. Confirm that your config file {{ configPath }} is valid YAML."
275
308
  },
276
- "getCWDAccountOverride": {
309
+ "buildConfigFromEnvironment": {
310
+ "missingAccountId": "HUBSPOT_ACCOUNT_ID is required, but not currently set",
311
+ "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."
312
+ }
313
+ },
314
+ "defaultAccountOverride": {
315
+ "getDefaultAccountOverrideAccountId": {
277
316
  "errorHeader": "Error in {{ hsAccountFile }}",
278
317
  "readFileError": "Error reading account override file."
279
- },
280
- "renameAccount": {
281
- "errors": {
282
- "invalidName": "Cannot find account with identifier {{ currentName }}"
283
- }
284
- },
285
- "removeAccountFromConfig": {
286
- "deleting": "Deleting config for {{ accountId }}",
287
- "errors": {
288
- "invalidId": "Unable to find account for {{ nameOrId }}."
289
- }
290
- },
291
- "updateDefaultCmsPublishMode": {
292
- "errors": {
293
- "invalidCmsPublishMode": "The CMS publish mode {{ defaultCmsPublishMode }} is invalid. Valid values are {{ validCmsPublishModes }}."
294
- }
295
- },
296
- "updateHttpTimeout": {
297
- "errors": {
298
- "invalidTimeout": "The value {{ timeout }} is invalid. The value must be a number greater than {{ minTimeout }}."
299
- }
300
- },
301
- "updateAllowUsageTracking": {
302
- "errors": {
303
- "invalidInput": "Unable to update allowUsageTracking. The value {{ isEnabled }} is invalid. The value must be a boolean."
304
- }
305
- },
306
- "updateAutoOpenBrowser": {
307
- "errors": {
308
- "invalidInput": "Unable to update autoOpenBrowser. The value {{ isEnabled }} is invalid. The value must be a boolean."
309
- }
310
318
  }
311
319
  },
320
+ "updateAllowUsageTracking": {
321
+ "invalidInput": "Unable to update allowUsageTracking. The value {{ isAllowed }} is invalid. The value must be a boolean."
322
+ },
323
+ "updateAllowAutoUpdates": {
324
+ "invalidInput": "Unable to update allowAutoUpdates. The value {{ isEnabled }} is invalid. The value must be a boolean."
325
+ },
326
+ "updateAutoOpenBrowser": {
327
+ "invalidInput": "Unable to update autoOpenBrowser. The value {{ isEnabled }} is invalid. The value must be a boolean."
328
+ },
312
329
  "configFile": {
313
330
  "errorReading": "Config file could not be read: {{ configPath }}",
314
331
  "writeSuccess": "Successfully wrote updated config data to {{ configPath }}",
@@ -327,9 +344,6 @@
327
344
  }
328
345
  },
329
346
  "getCurrentState": {
330
- "debug": {
331
- "emptyStateFile": "State file is empty, using default state"
332
- },
333
347
  "errors": {
334
348
  "errorReading": "Error reading CLI state, using defaults: {{ error }}"
335
349
  }
@@ -363,6 +377,9 @@
363
377
  "missingRefreshToken": "The account {{ accountId }} has not been authenticated with Oauth2",
364
378
  "auth": "Error while retrieving new token: {{ token }}"
365
379
  }
380
+ },
381
+ "HubSpotConfigError": {
382
+ "baseMessage": "An error occurred while {{ operation }} your HubSpot config {{ configType }}: {{ message }}"
366
383
  }
367
384
  },
368
385
  "utils": {
@@ -402,7 +419,8 @@
402
419
  },
403
420
  "errors": {
404
421
  "withOauth": "Oauth manager for account {{ accountId }} not found.",
405
- "withAuth": "Account with id {{ accountId }} not found."
422
+ "withAuth": "Account with id {{ accountId }} not found.",
423
+ "invalidAuthType": "Error authenticating HTTP request: account {{ accountId }} has an invalid auth type {{ authType }}"
406
424
  }
407
425
  }
408
426
  },
package/lib/cms/themes.js CHANGED
@@ -28,7 +28,9 @@ function getThemePreviewUrl(filePath, accountId) {
28
28
  const themeName = getThemeNameFromPath(filePath);
29
29
  if (!themeName)
30
30
  return;
31
- const baseUrl = (0, urls_1.getHubSpotWebsiteOrigin)((0, config_1.getEnv)(accountId) === 'qa' ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD);
31
+ const baseUrl = (0, urls_1.getHubSpotWebsiteOrigin)((0, config_1.getConfigAccountEnvironment)(accountId) === 'qa'
32
+ ? environments_1.ENVIRONMENTS.QA
33
+ : environments_1.ENVIRONMENTS.PROD);
32
34
  return `${baseUrl}/theme-previewer/${accountId}/edit/${encodeURIComponent(themeName)}`;
33
35
  }
34
36
  exports.getThemePreviewUrl = getThemePreviewUrl;
@@ -1,2 +1,2 @@
1
1
  import { Environment } from '../types/Config';
2
- export declare function getValidEnv(env?: Environment | null, maskedProductionValue?: Environment): Environment;
2
+ export declare function getValidEnv(env?: string | null, maskedProductionValue?: Environment): Environment;
package/lib/oauth.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { OAuth2Manager } from '../models/OAuth2Manager';
2
- import { FlatAccountFields } from '../types/Accounts';
3
- export declare function getOauthManager(accountId: number, accountConfig: FlatAccountFields): OAuth2Manager | undefined;
2
+ import { OAuthConfigAccount } from '../types/Accounts';
3
+ export declare function getOauthManager(account: OAuthConfigAccount): OAuth2Manager | undefined;
4
4
  export declare function addOauthToAccountConfig(oauth: OAuth2Manager): void;
package/lib/oauth.js CHANGED
@@ -2,33 +2,25 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.addOauthToAccountConfig = exports.getOauthManager = void 0;
4
4
  const OAuth2Manager_1 = require("../models/OAuth2Manager");
5
- const auth_1 = require("../constants/auth");
6
5
  const logger_1 = require("./logger");
7
- const getAccountIdentifier_1 = require("../config/getAccountIdentifier");
8
6
  const config_1 = require("../config");
9
7
  const lang_1 = require("../utils/lang");
10
8
  const i18nKey = 'lib.oauth';
11
9
  const oauthManagers = new Map();
12
- function writeOauthTokenInfo(accountConfig) {
13
- const accountId = (0, getAccountIdentifier_1.getAccountIdentifier)(accountConfig);
14
- logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.writeTokenInfo`, { portalId: accountId || '' }));
15
- (0, config_1.updateAccountConfig)(accountConfig);
16
- (0, config_1.writeConfig)();
10
+ function writeOauthTokenInfo(account) {
11
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.writeTokenInfo`, { portalId: account.accountId }));
12
+ (0, config_1.updateConfigAccount)(account);
17
13
  }
18
- function getOauthManager(accountId, accountConfig) {
19
- if (!oauthManagers.has(accountId)) {
20
- oauthManagers.set(accountId, OAuth2Manager_1.OAuth2Manager.fromConfig(accountConfig, () => writeOauthTokenInfo(accountConfig)));
14
+ function getOauthManager(account) {
15
+ if (!oauthManagers.has(account.accountId)) {
16
+ oauthManagers.set(account.accountId, new OAuth2Manager_1.OAuth2Manager(account, () => writeOauthTokenInfo(account)));
21
17
  }
22
- return oauthManagers.get(accountId);
18
+ return oauthManagers.get(account.accountId);
23
19
  }
24
20
  exports.getOauthManager = getOauthManager;
25
21
  function addOauthToAccountConfig(oauth) {
26
22
  logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.addOauthToAccountConfig.init`));
27
- (0, config_1.updateAccountConfig)({
28
- ...oauth.account,
29
- authType: auth_1.AUTH_METHODS.oauth.value,
30
- });
31
- (0, config_1.writeConfig)();
23
+ (0, config_1.updateConfigAccount)(oauth.account);
32
24
  logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.addOauthToAccountConfig.success`));
33
25
  }
34
26
  exports.addOauthToAccountConfig = addOauthToAccountConfig;
@@ -1,4 +1,4 @@
1
- import { CLIAccount, ScopeGroupAuthorization } from '../types/Accounts';
1
+ import { PersonalAccessKeyConfigAccount, ScopeGroupAuthorization } from '../types/Accounts';
2
2
  import { Environment } from '../types/Config';
3
3
  import { AccessToken } from '../types/Accounts';
4
4
  export declare function getAccessToken(personalAccessKey: string, env?: Environment, accountId?: number): Promise<AccessToken>;
@@ -8,4 +8,4 @@ export declare function enabledFeaturesForPersonalAccessKey(accountId: number):
8
8
  } | undefined>;
9
9
  export declare function scopesOnAccessToken(accountId: number): Promise<Array<string>>;
10
10
  export declare function authorizedScopesForPortalAndUser(accountId: number): Promise<Array<ScopeGroupAuthorization>>;
11
- export declare function updateConfigWithAccessToken(token: AccessToken, personalAccessKey: string, env?: Environment, name?: string, makeDefault?: boolean): Promise<CLIAccount | null>;
11
+ export declare function updateConfigWithAccessToken(token: AccessToken, personalAccessKey: string, env?: Environment, name?: string, makeDefault?: boolean): Promise<PersonalAccessKeyConfigAccount>;
@@ -13,7 +13,6 @@ const config_1 = require("../config");
13
13
  const config_2 = require("../constants/config");
14
14
  const developerTestAccounts_1 = require("../api/developerTestAccounts");
15
15
  const logger_1 = require("./logger");
16
- const CLIConfiguration_1 = require("../config/CLIConfiguration");
17
16
  const lang_1 = require("../utils/lang");
18
17
  const errors_1 = require("../errors");
19
18
  const i18nKey = 'lib.personalAccessKey';
@@ -36,30 +35,30 @@ async function getAccessToken(personalAccessKey, env = environments_1.ENVIRONMEN
36
35
  };
37
36
  }
38
37
  exports.getAccessToken = getAccessToken;
39
- async function refreshAccessToken(personalAccessKey, env = environments_1.ENVIRONMENTS.PROD, accountId) {
38
+ async function refreshAccessToken(account) {
39
+ const { personalAccessKey, env, accountId } = account;
40
40
  const accessTokenResponse = await getAccessToken(personalAccessKey, env, accountId);
41
41
  const { accessToken, expiresAt } = accessTokenResponse;
42
- const config = (0, config_1.getAccountConfig)(accountId);
43
- (0, config_1.updateAccountConfig)({
44
- env,
45
- ...config,
46
- accountId,
47
- tokenInfo: {
48
- accessToken,
49
- expiresAt: expiresAt,
42
+ (0, config_1.updateConfigAccount)({
43
+ ...account,
44
+ auth: {
45
+ tokenInfo: {
46
+ accessToken,
47
+ expiresAt: expiresAt,
48
+ },
50
49
  },
51
50
  });
52
- (0, config_1.writeConfig)();
53
51
  return accessTokenResponse;
54
52
  }
55
- async function getNewAccessToken(accountId, personalAccessKey, expiresAt, env) {
56
- const key = getRefreshKey(personalAccessKey, expiresAt);
53
+ async function getNewAccessToken(account) {
54
+ const { personalAccessKey, auth } = account;
55
+ const key = getRefreshKey(personalAccessKey, auth.tokenInfo.expiresAt);
57
56
  if (refreshRequests.has(key)) {
58
57
  return refreshRequests.get(key);
59
58
  }
60
59
  let accessTokenResponse;
61
60
  try {
62
- const refreshAccessPromise = refreshAccessToken(personalAccessKey, env, accountId);
61
+ const refreshAccessPromise = refreshAccessToken(account);
63
62
  if (key) {
64
63
  refreshRequests.set(key, refreshAccessPromise);
65
64
  }
@@ -74,28 +73,37 @@ async function getNewAccessToken(accountId, personalAccessKey, expiresAt, env) {
74
73
  return accessTokenResponse;
75
74
  }
76
75
  async function getNewAccessTokenByAccountId(accountId) {
77
- const account = (0, config_1.getAccountConfig)(accountId);
76
+ const account = (0, config_1.getConfigAccountById)(accountId);
78
77
  if (!account) {
79
78
  throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.accountNotFound`, { accountId }));
80
79
  }
81
- const { auth, personalAccessKey, env } = account;
82
- const accessTokenResponse = await getNewAccessToken(accountId, personalAccessKey, auth?.tokenInfo?.expiresAt, env);
80
+ if (account.authType !== auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value) {
81
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidAuthType`, {
82
+ accountId,
83
+ }));
84
+ }
85
+ const accessTokenResponse = await getNewAccessToken(account);
83
86
  return accessTokenResponse;
84
87
  }
85
88
  async function accessTokenForPersonalAccessKey(accountId, forceRefresh = false) {
86
- const account = (0, config_1.getAccountConfig)(accountId);
89
+ const account = (0, config_1.getConfigAccountById)(accountId);
87
90
  if (!account) {
88
91
  throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.accountNotFound`, { accountId }));
89
92
  }
90
- const { auth, personalAccessKey, env } = account;
93
+ if (account.authType !== auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value) {
94
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidAuthType`, {
95
+ accountId,
96
+ }));
97
+ }
98
+ const { auth } = account;
91
99
  const authTokenInfo = auth && auth.tokenInfo;
92
100
  const authDataExists = authTokenInfo && auth?.tokenInfo?.accessToken;
93
101
  if (!authDataExists ||
94
102
  forceRefresh ||
95
103
  (0, moment_1.default)().add(5, 'minutes').isAfter((0, moment_1.default)(authTokenInfo.expiresAt))) {
96
- return getNewAccessToken(accountId, personalAccessKey, authTokenInfo && authTokenInfo.expiresAt, env).then(tokenInfo => tokenInfo.accessToken);
104
+ return getNewAccessToken(account).then(tokenInfo => tokenInfo.accessToken);
97
105
  }
98
- return auth?.tokenInfo?.accessToken;
106
+ return auth.tokenInfo?.accessToken;
99
107
  }
100
108
  exports.accessTokenForPersonalAccessKey = accessTokenForPersonalAccessKey;
101
109
  async function enabledFeaturesForPersonalAccessKey(accountId) {
@@ -113,7 +121,10 @@ async function authorizedScopesForPortalAndUser(accountId) {
113
121
  exports.authorizedScopesForPortalAndUser = authorizedScopesForPortalAndUser;
114
122
  async function updateConfigWithAccessToken(token, personalAccessKey, env, name, makeDefault = false) {
115
123
  const { portalId, accessToken, expiresAt, accountType } = token;
116
- const accountEnv = env || (0, config_1.getEnv)(name);
124
+ const account = name
125
+ ? (0, config_1.getConfigAccountByName)(name)
126
+ : (0, config_1.getConfigDefaultAccount)();
127
+ const accountEnv = env || account.env;
117
128
  let parentAccountId;
118
129
  try {
119
130
  if (accountType === config_2.HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX ||
@@ -146,21 +157,19 @@ async function updateConfigWithAccessToken(token, personalAccessKey, env, name,
146
157
  }
147
158
  logger_1.logger.debug(err);
148
159
  }
149
- const updatedAccount = (0, config_1.updateAccountConfig)({
160
+ const updatedAccount = {
150
161
  accountId: portalId,
151
162
  accountType,
152
163
  personalAccessKey,
153
- name,
164
+ name: name || account.name,
154
165
  authType: auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value,
155
- tokenInfo: { accessToken, expiresAt },
166
+ auth: { tokenInfo: { accessToken, expiresAt } },
156
167
  parentAccountId,
157
168
  env: accountEnv,
158
- });
159
- if (!CLIConfiguration_1.CLIConfiguration.isActive()) {
160
- (0, config_1.writeConfig)();
161
- }
169
+ };
170
+ (0, config_1.updateConfigAccount)(updatedAccount);
162
171
  if (makeDefault && name) {
163
- (0, config_1.updateDefaultAccount)(name);
172
+ (0, config_1.setConfigAccountAsDefault)(name);
164
173
  }
165
174
  return updatedAccount;
166
175
  }
package/lib/trackUsage.js CHANGED
@@ -11,6 +11,7 @@ const http_1 = require("../http");
11
11
  const config_1 = require("../config");
12
12
  const fileMapper_1 = require("../api/fileMapper");
13
13
  const lang_1 = require("../utils/lang");
14
+ const environment_1 = require("./environment");
14
15
  const i18nKey = 'lib.trackUsage';
15
16
  async function trackUsage(eventName, eventClass, meta = {}, accountId) {
16
17
  const usageEvent = {
@@ -35,8 +36,8 @@ async function trackUsage(eventName, eventClass, meta = {}, accountId) {
35
36
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.invalidEvent`, { eventName }));
36
37
  }
37
38
  const path = `${fileMapper_1.FILE_MAPPER_API_PATH}/${analyticsEndpoint}`;
38
- const accountConfig = accountId && (0, config_1.getAccountConfig)(accountId);
39
- if (accountConfig && accountConfig.authType === 'personalaccesskey') {
39
+ const account = accountId && (0, config_1.getConfigAccountById)(accountId);
40
+ if (account && account.authType === 'personalaccesskey') {
40
41
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.sendingEventAuthenticated`));
41
42
  try {
42
43
  await http_1.http.post(accountId, {
@@ -50,7 +51,9 @@ async function trackUsage(eventName, eventClass, meta = {}, accountId) {
50
51
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.retryingEventUnauthenticated`));
51
52
  }
52
53
  }
53
- const env = (0, config_1.getEnv)(accountId);
54
+ const env = accountId
55
+ ? (0, config_1.getConfigAccountEnvironment)(accountId)
56
+ : (0, environment_1.getValidEnv)();
54
57
  const axiosConfig = (0, getAxiosConfig_1.getAxiosConfig)({
55
58
  env,
56
59
  url: path,
@@ -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, type: HubSpotConfigErrorType, operation: HubSpotConfigOperation, options?: ErrorOptions);
6
+ }
@@ -0,0 +1,29 @@
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
+ function isEnvironmentError(type) {
8
+ return type === config_1.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ENVIRONMENT_VARIABLES;
9
+ }
10
+ class HubSpotConfigError extends Error {
11
+ type;
12
+ operation;
13
+ constructor(message, type, operation, options) {
14
+ const configType = isEnvironmentError(type)
15
+ ? 'environment variables'
16
+ : 'file';
17
+ const operationText = operation === config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE ? 'writing to' : 'reading';
18
+ const withBaseMessage = (0, lang_1.i18n)('models.HubSpotConfigError.baseMessage', {
19
+ configType,
20
+ message,
21
+ operation: operationText,
22
+ });
23
+ super(withBaseMessage, options);
24
+ this.name = NAME;
25
+ this.type = type;
26
+ this.operation = operation;
27
+ }
28
+ }
29
+ exports.HubSpotConfigError = HubSpotConfigError;
@@ -1,12 +1,11 @@
1
- import { FlatAccountFields, OAuth2ManagerAccountConfig, WriteTokenInfoFunction, RefreshTokenResponse, ExchangeProof } from '../types/Accounts';
1
+ import { OAuthConfigAccount, WriteTokenInfoFunction, RefreshTokenResponse, ExchangeProof } from '../types/Accounts';
2
2
  export declare class OAuth2Manager {
3
- account: OAuth2ManagerAccountConfig;
3
+ account: OAuthConfigAccount;
4
4
  writeTokenInfo?: WriteTokenInfoFunction;
5
5
  refreshTokenRequest: Promise<RefreshTokenResponse> | null;
6
- constructor(account: OAuth2ManagerAccountConfig, writeTokenInfo?: WriteTokenInfoFunction);
6
+ constructor(account: OAuthConfigAccount, writeTokenInfo?: WriteTokenInfoFunction);
7
7
  accessToken(): Promise<string | undefined>;
8
8
  fetchAccessToken(exchangeProof: ExchangeProof): Promise<void>;
9
9
  exchangeForTokens(exchangeProof: ExchangeProof): Promise<void>;
10
10
  refreshAccessToken(): Promise<void>;
11
- static fromConfig(accountConfig: FlatAccountFields, writeTokenInfo: WriteTokenInfoFunction): OAuth2Manager;
12
11
  }
@@ -9,8 +9,6 @@ const moment_1 = __importDefault(require("moment"));
9
9
  const urls_1 = require("../lib/urls");
10
10
  const environment_1 = require("../lib/environment");
11
11
  const logger_1 = require("../lib/logger");
12
- const getAccountIdentifier_1 = require("../config/getAccountIdentifier");
13
- const auth_1 = require("../constants/auth");
14
12
  const lang_1 = require("../utils/lang");
15
13
  const i18nKey = 'models.OAuth2Manager';
16
14
  class OAuth2Manager {
@@ -26,23 +24,23 @@ class OAuth2Manager {
26
24
  }
27
25
  }
28
26
  async accessToken() {
29
- if (!this.account.tokenInfo?.refreshToken) {
27
+ if (!this.account.auth.tokenInfo.refreshToken) {
30
28
  throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.missingRefreshToken`, {
31
- accountId: (0, getAccountIdentifier_1.getAccountIdentifier)(this.account),
29
+ accountId: this.account.accountId,
32
30
  }));
33
31
  }
34
- if (!this.account.tokenInfo?.accessToken ||
32
+ if (!this.account.auth.tokenInfo.accessToken ||
35
33
  (0, moment_1.default)()
36
34
  .add(5, 'minutes')
37
- .isAfter((0, moment_1.default)(new Date(this.account.tokenInfo.expiresAt || '')))) {
35
+ .isAfter((0, moment_1.default)(new Date(this.account.auth.tokenInfo.expiresAt || '')))) {
38
36
  await this.refreshAccessToken();
39
37
  }
40
- return this.account.tokenInfo.accessToken;
38
+ return this.account.auth.tokenInfo.accessToken;
41
39
  }
42
40
  async fetchAccessToken(exchangeProof) {
43
41
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.fetchingAccessToken`, {
44
- accountId: (0, getAccountIdentifier_1.getAccountIdentifier)(this.account),
45
- clientId: this.account.clientId || '',
42
+ accountId: this.account.accountId,
43
+ clientId: this.account.auth.clientId,
46
44
  }));
47
45
  try {
48
46
  const { data } = await (0, axios_1.default)({
@@ -53,20 +51,20 @@ class OAuth2Manager {
53
51
  });
54
52
  this.refreshTokenRequest = data;
55
53
  const { refresh_token: refreshToken, access_token: accessToken, expires_in: expiresIn, } = data;
56
- if (!this.account.tokenInfo) {
57
- this.account.tokenInfo = {};
54
+ if (!this.account.auth.tokenInfo) {
55
+ this.account.auth.tokenInfo = {};
58
56
  }
59
- this.account.tokenInfo.refreshToken = refreshToken;
60
- this.account.tokenInfo.accessToken = accessToken;
61
- this.account.tokenInfo.expiresAt = (0, moment_1.default)()
57
+ this.account.auth.tokenInfo.refreshToken = refreshToken;
58
+ this.account.auth.tokenInfo.accessToken = accessToken;
59
+ this.account.auth.tokenInfo.expiresAt = (0, moment_1.default)()
62
60
  .add(Math.round(parseInt(expiresIn) * 0.75), 'seconds')
63
61
  .toString();
64
62
  if (this.writeTokenInfo) {
65
63
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.updatingTokenInfo`, {
66
- accountId: (0, getAccountIdentifier_1.getAccountIdentifier)(this.account),
67
- clientId: this.account.clientId || '',
64
+ accountId: this.account.accountId,
65
+ clientId: this.account.auth.clientId,
68
66
  }));
69
- this.writeTokenInfo(this.account.tokenInfo);
67
+ this.writeTokenInfo(this.account.auth.tokenInfo);
70
68
  }
71
69
  }
72
70
  finally {
@@ -76,8 +74,8 @@ class OAuth2Manager {
76
74
  async exchangeForTokens(exchangeProof) {
77
75
  if (this.refreshTokenRequest) {
78
76
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.refreshingAccessToken`, {
79
- accountId: (0, getAccountIdentifier_1.getAccountIdentifier)(this.account),
80
- clientId: this.account.clientId || '',
77
+ accountId: this.account.accountId,
78
+ clientId: this.account.auth.clientId,
81
79
  }));
82
80
  await this.refreshTokenRequest;
83
81
  }
@@ -88,18 +86,11 @@ class OAuth2Manager {
88
86
  async refreshAccessToken() {
89
87
  const refreshTokenProof = {
90
88
  grant_type: 'refresh_token',
91
- client_id: this.account.clientId,
92
- client_secret: this.account.clientSecret,
93
- refresh_token: this.account.tokenInfo?.refreshToken,
89
+ client_id: this.account.auth.clientId,
90
+ client_secret: this.account.auth.clientSecret,
91
+ refresh_token: this.account.auth.tokenInfo.refreshToken,
94
92
  };
95
93
  await this.exchangeForTokens(refreshTokenProof);
96
94
  }
97
- static fromConfig(accountConfig, writeTokenInfo) {
98
- return new OAuth2Manager({
99
- ...accountConfig,
100
- authType: auth_1.AUTH_METHODS.oauth.value,
101
- ...(accountConfig.auth || {}),
102
- }, writeTokenInfo);
103
- }
104
95
  }
105
96
  exports.OAuth2Manager = OAuth2Manager;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/local-dev-lib",
3
- "version": "0.4.3-experimental.0",
3
+ "version": "0.5.0-experimental.1",
4
4
  "description": "Provides library functionality for HubSpot local development tooling, including the HubSpot CLI",
5
5
  "repository": {
6
6
  "type": "git",
@@ -50,7 +50,7 @@
50
50
  "./errors/*": "./errors/*.js",
51
51
  "./http": "./http/index.js",
52
52
  "./http/*": "./http/*.js",
53
- "./config/getAccountIdentifier": "./config/getAccountIdentifier.js",
53
+ "./config/defaultAccountOverride": "./config/defaultAccountOverride.js",
54
54
  "./config/migrate": "./config/migrate.js",
55
55
  "./config/state": "./config/state.js",
56
56
  "./config": "./config/index.js",