@hubspot/cli 7.7.2-experimental.0 → 7.7.4-experimental.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,8 @@
1
1
  import { CommonArgs, ConfigArgs, YargsCommandModule } from '../../types/Yargs';
2
2
  type AccountAuthArgs = CommonArgs & ConfigArgs & {
3
3
  disableTracking?: boolean;
4
+ } & {
5
+ personalAccessKey?: string;
4
6
  };
5
7
  declare const accountAuthCommand: YargsCommandModule<unknown, AccountAuthArgs>;
6
8
  export default accountAuthCommand;
@@ -26,12 +26,14 @@ const TRACKING_STATUS = {
26
26
  COMPLETE: 'complete',
27
27
  };
28
28
  const authType = auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value;
29
- async function updateConfigWithNewAccount(env, configAlreadyExists, accountId) {
29
+ async function updateConfigWithNewAccount(env, configAlreadyExists, providedPersonalAccessKey, accountId) {
30
30
  try {
31
- const { personalAccessKey } = await (0, personalAccessKeyPrompt_1.personalAccessKeyPrompt)({
32
- env,
33
- account: accountId,
34
- });
31
+ const { personalAccessKey } = providedPersonalAccessKey
32
+ ? { personalAccessKey: providedPersonalAccessKey }
33
+ : await (0, personalAccessKeyPrompt_1.personalAccessKeyPrompt)({
34
+ env,
35
+ account: accountId,
36
+ });
35
37
  const token = await (0, personalAccessKey_1.getAccessToken)(personalAccessKey, env);
36
38
  const defaultAccountName = token.hubName
37
39
  ? (0, text_1.toKebabCase)(token.hubName)
@@ -96,7 +98,7 @@ async function handleConfigMigration() {
96
98
  const describe = en_1.commands.account.subcommands.auth.describe;
97
99
  const command = 'auth';
98
100
  async function handler(args) {
99
- const { providedAccountId, disableTracking } = args;
101
+ const { providedAccountId, disableTracking, personalAccessKey: providedPersonalAccessKey, } = args;
100
102
  if (!disableTracking) {
101
103
  (0, usageTracking_1.trackCommandUsage)('account-auth', {}, providedAccountId);
102
104
  await (0, usageTracking_1.trackAuthAction)('account-auth', authType, TRACKING_STATUS.STARTED);
@@ -112,7 +114,7 @@ async function handler(args) {
112
114
  }
113
115
  (0, config_1.loadConfig)('');
114
116
  (0, process_1.handleExit)(config_1.deleteEmptyConfigFile);
115
- const updatedConfig = await updateConfigWithNewAccount(args.qa ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD, configAlreadyExists, providedAccountId);
117
+ const updatedConfig = await updateConfigWithNewAccount(args.qa ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD, configAlreadyExists, providedPersonalAccessKey, providedAccountId);
116
118
  if (!updatedConfig) {
117
119
  if (!disableTracking) {
118
120
  await (0, usageTracking_1.trackAuthAction)('account-auth', authType, TRACKING_STATUS.ERROR);
@@ -151,6 +153,12 @@ function accountAuthBuilder(yargs) {
151
153
  hidden: true,
152
154
  default: false,
153
155
  },
156
+ 'personal-access-key': {
157
+ describe: en_1.commands.account.subcommands.auth.options.personalAccessKey,
158
+ type: 'string',
159
+ hidden: false,
160
+ alias: 'pak',
161
+ },
154
162
  });
155
163
  return yargs;
156
164
  }
@@ -1,6 +1,8 @@
1
1
  import { AccountArgs, CommonArgs, ConfigArgs, TestingArgs, YargsCommandModule } from '../types/Yargs';
2
2
  type AuthArgs = CommonArgs & ConfigArgs & TestingArgs & AccountArgs & {
3
3
  authType?: string;
4
+ } & {
5
+ personalAccessKey?: string;
4
6
  };
5
7
  declare const authCommand: YargsCommandModule<unknown, AuthArgs>;
6
8
  export default authCommand;
package/commands/auth.js CHANGED
@@ -20,6 +20,7 @@ const oauth_1 = require("../lib/oauth");
20
20
  const exitCodes_1 = require("../lib/enums/exitCodes");
21
21
  const ui_1 = require("../lib/ui");
22
22
  const index_1 = require("../lib/errorHandlers/index");
23
+ const en_1 = require("../lang/en");
23
24
  const TRACKING_STATUS = {
24
25
  STARTED: 'started',
25
26
  ERROR: 'error',
@@ -33,7 +34,7 @@ const SUPPORTED_AUTHENTICATION_PROTOCOLS_TEXT = (0, text_1.commaSeparatedValues)
33
34
  const command = 'auth';
34
35
  const describe = (0, lang_1.i18n)('commands.auth.describe');
35
36
  async function handler(args) {
36
- const { authType: authTypeFlagValue, config: configFlagValue, qa, providedAccountId, } = args;
37
+ const { authType: authTypeFlagValue, config: configFlagValue, qa, providedAccountId, personalAccessKey: providedPersonalAccessKey, } = args;
37
38
  const authType = (authTypeFlagValue && authTypeFlagValue.toLowerCase()) ||
38
39
  auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value;
39
40
  (0, commonOpts_1.setLogLevel)(args);
@@ -68,14 +69,16 @@ async function handler(args) {
68
69
  successAuthMethod = auth_1.OAUTH_AUTH_METHOD.name;
69
70
  break;
70
71
  case auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value:
71
- configData = await (0, personalAccessKeyPrompt_1.personalAccessKeyPrompt)({
72
- env,
73
- account: providedAccountId,
74
- });
72
+ const { personalAccessKey } = providedPersonalAccessKey
73
+ ? { personalAccessKey: providedPersonalAccessKey }
74
+ : await (0, personalAccessKeyPrompt_1.personalAccessKeyPrompt)({
75
+ env,
76
+ account: providedAccountId,
77
+ });
75
78
  try {
76
- token = await (0, personalAccessKey_1.getAccessToken)(configData.personalAccessKey, env);
79
+ token = await (0, personalAccessKey_1.getAccessToken)(personalAccessKey, env);
77
80
  defaultName = token.hubName ? (0, text_1.toKebabCase)(token.hubName) : undefined;
78
- updatedConfig = await (0, personalAccessKey_1.updateConfigWithAccessToken)(token, configData.personalAccessKey, env);
81
+ updatedConfig = await (0, personalAccessKey_1.updateConfigWithAccessToken)(token, personalAccessKey, env);
79
82
  }
80
83
  catch (e) {
81
84
  (0, index_1.logError)(e);
@@ -108,7 +111,7 @@ async function handler(args) {
108
111
  await (0, usageTracking_1.trackAuthAction)('auth', authType, TRACKING_STATUS.ERROR, providedAccountId);
109
112
  process.exit(exitCodes_1.EXIT_CODES.ERROR);
110
113
  }
111
- const nameFromConfigData = 'name' in configData ? configData.name : undefined;
114
+ const nameFromConfigData = configData && 'name' in configData ? configData.name : undefined;
112
115
  const accountName = (updatedConfig && updatedConfig.name) || validName || nameFromConfigData;
113
116
  await (0, setAsDefaultAccountPrompt_1.setAsDefaultAccountPrompt)(accountName);
114
117
  logger_1.logger.success((0, lang_1.i18n)('commands.auth.success.configFileUpdated', {
@@ -141,6 +144,12 @@ function authBuilder(yargs) {
141
144
  type: 'string',
142
145
  alias: 'a',
143
146
  },
147
+ 'personal-access-key': {
148
+ describe: en_1.commands.auth.options.personalAccessKey.describe,
149
+ type: 'string',
150
+ hidden: false,
151
+ alias: 'pak',
152
+ },
144
153
  });
145
154
  return yargs;
146
155
  }
@@ -0,0 +1,4 @@
1
+ import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModule } from '../../types/Yargs';
2
+ type HubdbListArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs;
3
+ declare const hubdbListCommand: YargsCommandModule<unknown, HubdbListArgs>;
4
+ export default hubdbListCommand;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const hubdb_1 = require("@hubspot/local-dev-lib/api/hubdb");
4
+ const config_1 = require("@hubspot/local-dev-lib/config");
5
+ const urls_1 = require("@hubspot/local-dev-lib/urls");
6
+ const exitCodes_1 = require("../../lib/enums/exitCodes");
7
+ const logger_1 = require("../../lib/ui/logger");
8
+ const index_1 = require("../../lib/errorHandlers/index");
9
+ const en_1 = require("../../lang/en");
10
+ const yargsUtils_1 = require("../../lib/yargsUtils");
11
+ const usageTracking_1 = require("../../lib/usageTracking");
12
+ const table_1 = require("../../lib/ui/table");
13
+ const command = ['list', 'ls'];
14
+ const describe = en_1.commands.hubdb.subcommands.list.describe;
15
+ async function getTableData(accountId) {
16
+ try {
17
+ const response = await (0, hubdb_1.fetchTables)(accountId);
18
+ return response.data;
19
+ }
20
+ catch (err) {
21
+ (0, index_1.logError)(err);
22
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
23
+ }
24
+ }
25
+ // stripping the types and unnecessary fields so this data can be turned into a UI table
26
+ function mapTablesToUI(tables) {
27
+ return tables.map(({ id, label, name, columnCount, rowCount }) => [
28
+ `${id}`,
29
+ label,
30
+ name,
31
+ `${columnCount || 0}`,
32
+ `${rowCount}`,
33
+ ]);
34
+ }
35
+ async function handler(args) {
36
+ const { derivedAccountId } = args;
37
+ (0, usageTracking_1.trackCommandUsage)('hubdb-list', {}, derivedAccountId);
38
+ const { results: tables, total } = await getTableData(derivedAccountId);
39
+ const tableUIData = mapTablesToUI(tables);
40
+ tableUIData.unshift((0, table_1.getTableHeader)([
41
+ en_1.commands.hubdb.subcommands.list.labels.id,
42
+ en_1.commands.hubdb.subcommands.list.labels.label,
43
+ en_1.commands.hubdb.subcommands.list.labels.name,
44
+ en_1.commands.hubdb.subcommands.list.labels.columns,
45
+ en_1.commands.hubdb.subcommands.list.labels.rows,
46
+ ]));
47
+ logger_1.uiLogger.success(en_1.commands.hubdb.subcommands.list.success(derivedAccountId));
48
+ logger_1.uiLogger.log(' ');
49
+ // link devs to the hubdb page in hubspot for easy access
50
+ // TODO: This is hacky, we should make a util like getBaseUrl()
51
+ const baseUrl = (0, urls_1.getHubSpotWebsiteOrigin)((0, config_1.getEnv)());
52
+ logger_1.uiLogger.log(en_1.commands.hubdb.subcommands.list.viewTablesLink(baseUrl, derivedAccountId));
53
+ // don't bother showing an empty list of tables
54
+ if (tables.length > 0) {
55
+ // if truncated is 0, it will be interpreted as falsy
56
+ const truncated = total - tables.length;
57
+ logger_1.uiLogger.log(en_1.commands.hubdb.subcommands.list.tablesDisplayed(tables.length, total, truncated));
58
+ logger_1.uiLogger.log('--------------------------------');
59
+ logger_1.uiLogger.log(en_1.commands.hubdb.subcommands.list.tables);
60
+ logger_1.uiLogger.log((0, table_1.getTableContents)(tableUIData, { border: { bodyLeft: ' ' } }));
61
+ }
62
+ else {
63
+ logger_1.uiLogger.log(en_1.commands.hubdb.subcommands.list.noTables(derivedAccountId));
64
+ }
65
+ process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
66
+ }
67
+ function hubdbListBuilder(yargs) {
68
+ yargs.example([['$0 hubdb list']]);
69
+ return yargs;
70
+ }
71
+ const builder = (0, yargsUtils_1.makeYargsBuilder)(hubdbListBuilder, command, describe, {
72
+ useGlobalOptions: true,
73
+ useConfigOptions: true,
74
+ useAccountOptions: true,
75
+ useEnvironmentOptions: true,
76
+ });
77
+ const hubdbListCommand = {
78
+ command,
79
+ describe,
80
+ handler,
81
+ builder,
82
+ };
83
+ exports.default = hubdbListCommand;
package/commands/hubdb.js CHANGED
@@ -8,6 +8,7 @@ const create_1 = __importDefault(require("./hubdb/create"));
8
8
  const fetch_1 = __importDefault(require("./hubdb/fetch"));
9
9
  const delete_1 = __importDefault(require("./hubdb/delete"));
10
10
  const clear_1 = __importDefault(require("./hubdb/clear"));
11
+ const list_1 = __importDefault(require("./hubdb/list"));
11
12
  const lang_1 = require("../lib/lang");
12
13
  const yargsUtils_1 = require("../lib/yargsUtils");
13
14
  exports.command = 'hubdb';
@@ -18,6 +19,7 @@ function hubdbBuilder(yargs) {
18
19
  .command(create_1.default)
19
20
  .command(fetch_1.default)
20
21
  .command(delete_1.default)
22
+ .command(list_1.default)
21
23
  .demandCommand(1, '');
22
24
  return yargs;
23
25
  }
@@ -24,6 +24,7 @@ const accountTypes_1 = require("../../../lib/accountTypes");
24
24
  const ui_1 = require("../../../lib/ui");
25
25
  const logger_1 = require("../../../lib/ui/logger");
26
26
  const en_1 = require("../../../lang/en");
27
+ const LocalDevWebsocketServer_1 = __importDefault(require("../../../lib/projects/localDev/LocalDevWebsocketServer"));
27
28
  async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTargetTestingAccountId, projectConfig, projectDir, profileConfig, }) {
28
29
  const env = (0, environment_1.getValidEnv)((0, config_2.getEnv)(targetProjectAccountId));
29
30
  let projectNodes;
@@ -131,23 +132,20 @@ async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTar
131
132
  await localDevProcess.start();
132
133
  const watcher = new LocalDevWatcher_1.default(localDevProcess);
133
134
  watcher.start();
134
- // const websocketServer = new LocalDevWebsocketServer(
135
- // localDevProcess,
136
- // args.debug
137
- // );
138
- // await websocketServer.start();
135
+ const websocketServer = new LocalDevWebsocketServer_1.default(localDevProcess, args.debug);
136
+ await websocketServer.start();
139
137
  (0, process_1.handleKeypress)(async (key) => {
140
138
  if ((key.ctrl && key.name === 'c') || key.name === 'q') {
141
139
  await Promise.all([
142
140
  localDevProcess.stop(),
143
141
  watcher.stop(),
144
- // websocketServer.shutdown(),
142
+ websocketServer.shutdown(),
145
143
  ]);
146
144
  }
147
145
  });
148
146
  (0, process_1.handleExit)(({ isSIGHUP }) => {
149
147
  localDevProcess.stop(!isSIGHUP);
150
148
  watcher.stop();
151
- // websocketServer.shutdown();
149
+ websocketServer.shutdown();
152
150
  });
153
151
  }
package/lang/en.d.ts CHANGED
@@ -26,6 +26,7 @@ The authentication method is ${string}, which is an access token tied to a speci
26
26
  Global configuration replaces hubspot.config.yml, and you will be prompted to migrate your existing config if one exists.`;
27
27
  readonly options: {
28
28
  readonly account: "HubSpot account to authenticate";
29
+ readonly personalAccessKey: "Enter existing personal access key";
29
30
  };
30
31
  readonly errors: {
31
32
  readonly failedToUpdateConfig: "Failed to update the configuration file. Please try again.";
@@ -153,6 +154,9 @@ Global configuration replaces hubspot.config.yml, and you will be prompted to mi
153
154
  readonly account: {
154
155
  readonly describe: "HubSpot account to authenticate";
155
156
  };
157
+ readonly personalAccessKey: {
158
+ readonly describe: "Enter existing personal access key";
159
+ };
156
160
  };
157
161
  readonly success: {
158
162
  readonly configFileUpdated: (accountName: string, configFilename: string, authType: string) => string;
@@ -665,6 +669,21 @@ Global configuration replaces hubspot.config.yml, and you will be prompted to mi
665
669
  readonly fetch: (tableId: string, path: string) => string;
666
670
  };
667
671
  };
672
+ readonly list: {
673
+ readonly tables: `${string}:`;
674
+ readonly describe: "List HubDB tables.";
675
+ readonly labels: {
676
+ readonly label: "Label";
677
+ readonly id: "ID";
678
+ readonly name: "Name";
679
+ readonly columns: "Columns";
680
+ readonly rows: "Rows";
681
+ };
682
+ readonly success: (accountId: number) => string;
683
+ readonly noTables: (accountId: number) => string;
684
+ readonly tablesDisplayed: (displayed: number, total: number, truncated?: number) => string;
685
+ readonly viewTablesLink: (baseUrl: string, accountId: number) => string;
686
+ };
668
687
  };
669
688
  };
670
689
  readonly init: {
@@ -2258,6 +2277,7 @@ export declare const lib: {
2258
2277
  readonly running: (projectName: string, accountIdentifier: string) => string;
2259
2278
  readonly quitHelper: `Press ${string} to stop the local dev server`;
2260
2279
  readonly viewProjectLink: (name: string, accountId: number) => string;
2280
+ readonly viewLocalDevUILink: (accountId: number) => string;
2261
2281
  readonly viewTestAccountLink: "View developer test account in HubSpot";
2262
2282
  readonly exitingStart: "Stopping local dev server ...";
2263
2283
  readonly exitingSucceed: "Successfully exited";
@@ -2664,11 +2684,14 @@ Run ${string} to upgrade to version ${string}`;
2664
2684
  readonly enterAccountId: "Enter the account ID for your account (the number under the DOMAIN column at https://app.hubspot.com/myaccounts-beta ): ";
2665
2685
  readonly enterClientId: "Enter your OAuth2 client ID: ";
2666
2686
  readonly enterClientSecret: "Enter your OAuth2 client secret: ";
2667
- readonly enterPersonalAccessKey: "Enter your personal access key: ";
2687
+ readonly enterPersonalAccessKey: "[--personal-access-key] Enter your personal access key: ";
2668
2688
  readonly selectScopes: "Select access scopes (see https://developers.hubspot.com/docs/methods/oauth2/initiate-oauth-integration#scopes)";
2669
2689
  readonly personalAccessKeySetupTitle: "HubSpot Personal Access Key Setup";
2670
- readonly personalAccessKeyBrowserOpenPrep: "A personal access key is required to authenticate the CLI to interact with your HubSpot account. We'll open a secure page in your default browser where you can view and copy your personal access key.";
2671
- readonly personalAccessKeyBrowserOpenPrompt: "Open HubSpot to copy your personal access key?";
2690
+ readonly personalAccessKeyBrowserOpenPrep: "A personal access key is required to authenticate the CLI to interact with your HubSpot account.";
2691
+ readonly personalAccessKeyPromptChoices: {
2692
+ readonly OPEN_BROWSER: "Open HubSpot to copy your personal access key";
2693
+ readonly PASTE_EXISTING: "Enter existing personal access key";
2694
+ };
2672
2695
  readonly logs: {
2673
2696
  readonly openingWebBrowser: (url: string) => string;
2674
2697
  };
package/lang/en.js CHANGED
@@ -36,6 +36,7 @@ exports.commands = {
36
36
  verboseDescribe: `Configure authentication for a HubSpot account. This will create or update the global config file at ${config_1.GLOBAL_CONFIG_PATH} that stores your account information.\n\nThe authentication method is ${chalk_1.default.bold(auth_1.PERSONAL_ACCESS_KEY_AUTH_METHOD.value)}, which is an access token tied to a specific user account.\n\nGlobal configuration replaces ${config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME}, and you will be prompted to migrate your existing config if one exists.`,
37
37
  options: {
38
38
  account: 'HubSpot account to authenticate',
39
+ personalAccessKey: 'Enter existing personal access key',
39
40
  },
40
41
  errors: {
41
42
  failedToUpdateConfig: 'Failed to update the configuration file. Please try again.',
@@ -163,6 +164,9 @@ exports.commands = {
163
164
  account: {
164
165
  describe: 'HubSpot account to authenticate',
165
166
  },
167
+ personalAccessKey: {
168
+ describe: 'Enter existing personal access key',
169
+ },
166
170
  },
167
171
  success: {
168
172
  configFileUpdated: (accountName, configFilename, authType) => `Account "${accountName}" updated in ${configFilename} using "${authType}"`,
@@ -675,6 +679,23 @@ exports.commands = {
675
679
  fetch: (tableId, path) => `Downloaded HubDB table ${tableId} to ${path}`,
676
680
  },
677
681
  },
682
+ list: {
683
+ tables: `${chalk_1.default.bold('Tables')}:`,
684
+ describe: 'List HubDB tables.',
685
+ labels: {
686
+ label: 'Label',
687
+ id: 'ID',
688
+ name: 'Name',
689
+ columns: 'Columns',
690
+ rows: 'Rows',
691
+ },
692
+ success: (accountId) => `Showing tables for account ${accountId}:`,
693
+ noTables: (accountId) => `No tables found for account ${accountId}.`,
694
+ tablesDisplayed: (displayed, total, truncated) => `Displaying ${displayed} of ${total} tables${truncated
695
+ ? `, the remaining ${truncated} tables were not displayed.`
696
+ : '.'}`,
697
+ viewTablesLink: (baseUrl, accountId) => (0, ui_1.uiLink)('Manage tables in HubSpot', `${baseUrl}/hubdb/${accountId}`),
698
+ },
678
699
  },
679
700
  },
680
701
  init: {
@@ -2257,6 +2278,7 @@ exports.lib = {
2257
2278
  running: (projectName, accountIdentifier) => chalk_1.default.hex(ui_1.UI_COLORS.SORBET)(`Running ${chalk_1.default.bold(projectName)} locally on ${accountIdentifier}, waiting for changes ...`),
2258
2279
  quitHelper: `Press ${chalk_1.default.bold('q')} to stop the local dev server`,
2259
2280
  viewProjectLink: (name, accountId) => (0, ui_1.uiLink)('View project in HubSpot', (0, urls_1.getProjectDetailUrl)(name, accountId) || ''),
2281
+ viewLocalDevUILink: (accountId) => (0, ui_1.uiLink)('View local dev session in HubSpot', (0, urls_1.getLocalDevUiUrl)(accountId)),
2260
2282
  viewTestAccountLink: 'View developer test account in HubSpot',
2261
2283
  exitingStart: 'Stopping local dev server ...',
2262
2284
  exitingSucceed: 'Successfully exited',
@@ -2660,11 +2682,14 @@ exports.lib = {
2660
2682
  enterAccountId: 'Enter the account ID for your account (the number under the DOMAIN column at https://app.hubspot.com/myaccounts-beta ): ',
2661
2683
  enterClientId: 'Enter your OAuth2 client ID: ',
2662
2684
  enterClientSecret: 'Enter your OAuth2 client secret: ',
2663
- enterPersonalAccessKey: 'Enter your personal access key: ',
2685
+ enterPersonalAccessKey: '[--personal-access-key] Enter your personal access key: ',
2664
2686
  selectScopes: 'Select access scopes (see https://developers.hubspot.com/docs/methods/oauth2/initiate-oauth-integration#scopes)',
2665
2687
  personalAccessKeySetupTitle: 'HubSpot Personal Access Key Setup',
2666
- personalAccessKeyBrowserOpenPrep: "A personal access key is required to authenticate the CLI to interact with your HubSpot account. We'll open a secure page in your default browser where you can view and copy your personal access key.",
2667
- personalAccessKeyBrowserOpenPrompt: 'Open HubSpot to copy your personal access key?',
2688
+ personalAccessKeyBrowserOpenPrep: 'A personal access key is required to authenticate the CLI to interact with your HubSpot account.',
2689
+ personalAccessKeyPromptChoices: {
2690
+ OPEN_BROWSER: 'Open HubSpot to copy your personal access key',
2691
+ PASTE_EXISTING: 'Enter existing personal access key',
2692
+ },
2668
2693
  logs: {
2669
2694
  openingWebBrowser: (url) => `Opening ${url} in your web browser`,
2670
2695
  },
@@ -101,6 +101,7 @@ class LocalDevLogger {
101
101
  logger_2.uiLogger.log('');
102
102
  logger_2.uiLogger.log(en_1.lib.LocalDevManager.running(this.state.projectConfig.name, (0, ui_1.uiAccountDescription)(this.state.targetProjectAccountId)));
103
103
  logger_2.uiLogger.log(en_1.lib.LocalDevManager.viewProjectLink(this.state.projectConfig.name, this.state.targetProjectAccountId));
104
+ logger_2.uiLogger.log(en_1.lib.LocalDevManager.viewLocalDevUILink(this.state.targetTestingAccountId));
104
105
  logger_2.uiLogger.log('');
105
106
  logger_2.uiLogger.log(en_1.lib.LocalDevManager.quitHelper);
106
107
  (0, ui_1.uiLine)();
@@ -13,8 +13,8 @@ class LocalDevWebsocketServer {
13
13
  debug;
14
14
  localDevProcess;
15
15
  ALLOWED_ORIGINS = [
16
- 'https://hubspot.com',
17
- 'https://hubspotqa.com',
16
+ 'https://app.hubspot.com',
17
+ 'https://app.hubspotqa.com',
18
18
  'https://local.hubspot.com',
19
19
  'https://local.hubspotqa.com',
20
20
  ];
@@ -3,3 +3,4 @@ export declare function getProjectSettingsUrl(projectName: string, accountId: nu
3
3
  export declare function getProjectActivityUrl(projectName: string, accountId: number): string;
4
4
  export declare function getProjectBuildDetailUrl(projectName: string, buildId: number, accountId: number): string;
5
5
  export declare function getProjectDeployDetailUrl(projectName: string, deployId: number, accountId: number): string;
6
+ export declare function getLocalDevUiUrl(accountId: number): string;
@@ -5,12 +5,15 @@ exports.getProjectSettingsUrl = getProjectSettingsUrl;
5
5
  exports.getProjectActivityUrl = getProjectActivityUrl;
6
6
  exports.getProjectBuildDetailUrl = getProjectBuildDetailUrl;
7
7
  exports.getProjectDeployDetailUrl = getProjectDeployDetailUrl;
8
+ exports.getLocalDevUiUrl = getLocalDevUiUrl;
8
9
  const urls_1 = require("@hubspot/local-dev-lib/urls");
9
10
  const config_1 = require("@hubspot/local-dev-lib/config");
10
11
  const environments_1 = require("@hubspot/local-dev-lib/constants/environments");
12
+ function getBaseUrl(accountId) {
13
+ return (0, urls_1.getHubSpotWebsiteOrigin)((0, config_1.getEnv)(accountId) === 'qa' ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD);
14
+ }
11
15
  function getProjectHomeUrl(accountId) {
12
- const baseUrl = (0, urls_1.getHubSpotWebsiteOrigin)((0, config_1.getEnv)(accountId) === 'qa' ? environments_1.ENVIRONMENTS.QA : environments_1.ENVIRONMENTS.PROD);
13
- return `${baseUrl}/developer-projects/${accountId}`;
16
+ return `${getBaseUrl(accountId)}/developer-projects/${accountId}`;
14
17
  }
15
18
  function getProjectDetailUrl(projectName, accountId) {
16
19
  if (!projectName)
@@ -31,3 +34,6 @@ function getProjectBuildDetailUrl(projectName, buildId, accountId) {
31
34
  function getProjectDeployDetailUrl(projectName, deployId, accountId) {
32
35
  return `${getProjectActivityUrl(projectName, accountId)}/deploy/${deployId}`;
33
36
  }
37
+ function getLocalDevUiUrl(accountId) {
38
+ return `${getBaseUrl(accountId)}/developer-projects-local-dev/${accountId}`;
39
+ }
@@ -12,9 +12,9 @@ const urls_1 = require("@hubspot/local-dev-lib/urls");
12
12
  const logger_1 = require("@hubspot/local-dev-lib/logger");
13
13
  const promptUtils_1 = require("./promptUtils");
14
14
  const accountNamePrompt_1 = require("./accountNamePrompt");
15
- const lang_1 = require("../lang");
16
15
  const ui_1 = require("../ui");
17
16
  const exitCodes_1 = require("../enums/exitCodes");
17
+ const en_1 = require("../../lang/en");
18
18
  /**
19
19
  * Displays notification to user that we are about to open the browser,
20
20
  * then opens their browser to the personal-access-key shortlink
@@ -23,24 +23,26 @@ async function personalAccessKeyPrompt({ env, account, }) {
23
23
  const websiteOrigin = (0, urls_1.getHubSpotWebsiteOrigin)(env);
24
24
  let url = `${websiteOrigin}/l/personal-access-key`;
25
25
  if (process.env.BROWSER !== 'none') {
26
- (0, ui_1.uiInfoSection)((0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.personalAccessKeySetupTitle`), () => {
27
- logger_1.logger.log((0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.personalAccessKeyBrowserOpenPrep`));
26
+ (0, ui_1.uiInfoSection)(en_1.lib.prompts.personalAccessKeyPrompt.personalAccessKeySetupTitle, () => {
27
+ logger_1.logger.log(en_1.lib.prompts.personalAccessKeyPrompt.personalAccessKeyBrowserOpenPrep);
28
28
  });
29
29
  if (account) {
30
30
  url = `${websiteOrigin}/personal-access-key/${account}`;
31
31
  }
32
- const { personalAcessKeyBrowserOpenPrep: shouldOpen } = await (0, promptUtils_1.promptUser)([
32
+ const { personalAcessKeyBrowserOpenPrep: choice } = await (0, promptUtils_1.promptUser)([
33
33
  PERSONAL_ACCESS_KEY_BROWSER_OPEN_PREP,
34
34
  ]);
35
- if (shouldOpen) {
36
- (0, open_1.default)(url, { url: true });
37
- }
38
- else {
35
+ if (!choice) {
39
36
  (0, config_1.deleteEmptyConfigFile)();
40
37
  process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
41
38
  }
39
+ if (choice ===
40
+ en_1.lib.prompts.personalAccessKeyPrompt.personalAccessKeyPromptChoices
41
+ .OPEN_BROWSER) {
42
+ (0, open_1.default)(url, { url: true });
43
+ logger_1.logger.log(en_1.lib.prompts.personalAccessKeyPrompt.logs.openingWebBrowser(url));
44
+ }
42
45
  }
43
- logger_1.logger.log((0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.logs.openingWebBrowser`, { url }));
44
46
  const { personalAccessKey } = await (0, promptUtils_1.promptUser)(PERSONAL_ACCESS_KEY);
45
47
  return {
46
48
  personalAccessKey,
@@ -49,52 +51,59 @@ async function personalAccessKeyPrompt({ env, account, }) {
49
51
  }
50
52
  const ACCOUNT_ID = {
51
53
  name: 'accountId',
52
- message: (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.enterAccountId`),
54
+ message: en_1.lib.prompts.personalAccessKeyPrompt.enterAccountId,
53
55
  type: 'number',
54
56
  validate(val) {
55
57
  if (!Number.isNaN(val) && val !== undefined && val > 0) {
56
58
  return true;
57
59
  }
58
- return (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.errors.invalidAccountId`);
60
+ return en_1.lib.prompts.personalAccessKeyPrompt.errors.invalidAccountId;
59
61
  },
60
62
  };
61
63
  const CLIENT_ID = {
62
64
  name: 'clientId',
63
- message: (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.enterClientId`),
65
+ message: en_1.lib.prompts.personalAccessKeyPrompt.enterClientId,
64
66
  validate(val) {
65
67
  if (typeof val !== 'string') {
66
- return (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.errors.invalidOauthClientId`);
68
+ return en_1.lib.prompts.personalAccessKeyPrompt.errors.invalidOauthClientId;
67
69
  }
68
70
  else if (val.length !== 36) {
69
- return (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.errors.invalidOauthClientIdLength`);
71
+ return en_1.lib.prompts.personalAccessKeyPrompt.errors
72
+ .invalidOauthClientIdLength;
70
73
  }
71
74
  return true;
72
75
  },
73
76
  };
74
77
  const CLIENT_SECRET = {
75
78
  name: 'clientSecret',
76
- message: (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.enterClientSecret`),
79
+ message: en_1.lib.prompts.personalAccessKeyPrompt.enterClientSecret,
77
80
  validate(val) {
78
81
  if (typeof val !== 'string') {
79
- return (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.errors.invalidOauthClientSecret`);
82
+ return en_1.lib.prompts.personalAccessKeyPrompt.errors
83
+ .invalidOauthClientSecret;
80
84
  }
81
85
  else if (val.length !== 36) {
82
- return (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.errors.invalidOauthClientSecretLength`);
86
+ return en_1.lib.prompts.personalAccessKeyPrompt.errors
87
+ .invalidOauthClientSecretLength;
83
88
  }
84
89
  else if (val[0] === '*') {
85
- return (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.errors.invalidOauthClientSecretCopy`);
90
+ return en_1.lib.prompts.personalAccessKeyPrompt.errors
91
+ .invalidOauthClientSecretCopy;
86
92
  }
87
93
  return true;
88
94
  },
89
95
  };
90
96
  const PERSONAL_ACCESS_KEY_BROWSER_OPEN_PREP = {
91
97
  name: 'personalAcessKeyBrowserOpenPrep',
92
- type: 'confirm',
93
- message: (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.personalAccessKeyBrowserOpenPrompt`),
98
+ type: 'list',
99
+ message: 'Choose your preferred method of authentication',
100
+ choices: Object.values(en_1.lib.prompts.personalAccessKeyPrompt.personalAccessKeyPromptChoices),
101
+ default: en_1.lib.prompts.personalAccessKeyPrompt.personalAccessKeyPromptChoices
102
+ .OPEN_BROWSER,
94
103
  };
95
104
  const PERSONAL_ACCESS_KEY = {
96
105
  name: 'personalAccessKey',
97
- message: (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.enterPersonalAccessKey`),
106
+ message: en_1.lib.prompts.personalAccessKeyPrompt.enterPersonalAccessKey,
98
107
  transformer: (val) => {
99
108
  if (!val)
100
109
  return val;
@@ -106,10 +115,12 @@ const PERSONAL_ACCESS_KEY = {
106
115
  },
107
116
  validate(val) {
108
117
  if (!val || typeof val !== 'string') {
109
- return (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.errors.invalidPersonalAccessKey`);
118
+ return en_1.lib.prompts.personalAccessKeyPrompt.errors
119
+ .invalidPersonalAccessKey;
110
120
  }
111
121
  else if (val[0] === '•') {
112
- return (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.errors.invalidPersonalAccessKeyCopy`);
122
+ return en_1.lib.prompts.personalAccessKeyPrompt.errors
123
+ .invalidPersonalAccessKeyCopy;
113
124
  }
114
125
  return true;
115
126
  },
@@ -117,7 +128,7 @@ const PERSONAL_ACCESS_KEY = {
117
128
  const SCOPES = {
118
129
  type: 'checkbox',
119
130
  name: 'scopes',
120
- message: (0, lang_1.i18n)(`lib.prompts.personalAccessKeyPrompt.selectScopes`),
131
+ message: en_1.lib.prompts.personalAccessKeyPrompt.selectScopes,
121
132
  default: [...auth_1.DEFAULT_OAUTH_SCOPES],
122
133
  choices: [...auth_1.OAUTH_SCOPES],
123
134
  };
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "7.7.2-experimental.0",
3
+ "version": "7.7.4-experimental.0",
4
4
  "description": "The official CLI for developing on HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "https://github.com/HubSpot/hubspot-cli",
7
7
  "dependencies": {
8
8
  "@hubspot/local-dev-lib": "3.7.1",
9
- "@hubspot/project-parsing-lib": "0.3.1-beta.0",
10
- "@hubspot/serverless-dev-runtime": "7.0.2",
9
+ "@hubspot/project-parsing-lib": "0.3.2-beta.0",
10
+ "@hubspot/serverless-dev-runtime": "7.0.6",
11
11
  "@hubspot/theme-preview-dev-server": "0.0.10",
12
12
  "@hubspot/ui-extensions-dev-server": "0.9.2",
13
13
  "archiver": "7.0.1",