@hubspot/cli 3.0.10-beta.9 → 3.0.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.
Files changed (90) hide show
  1. package/README.md +7 -1
  2. package/bin/cli.js +3 -4
  3. package/commands/accounts/list.js +18 -26
  4. package/commands/accounts/rename.js +13 -24
  5. package/commands/accounts.js +4 -1
  6. package/commands/auth.js +33 -16
  7. package/commands/config/set/allowUsageTracking.js +17 -33
  8. package/commands/config/set/defaultAccount.js +24 -34
  9. package/commands/config/set/defaultMode.js +25 -44
  10. package/commands/config/set/httpTimeout.js +10 -28
  11. package/commands/config/set.js +4 -1
  12. package/commands/config.js +4 -1
  13. package/commands/create/api-sample.js +20 -14
  14. package/commands/create/function.js +3 -1
  15. package/commands/create/index.js +0 -1
  16. package/commands/create/module.js +20 -7
  17. package/commands/create/template.js +22 -5
  18. package/commands/create/website-theme.js +12 -1
  19. package/commands/create.js +23 -8
  20. package/commands/customObject/create.js +22 -24
  21. package/commands/customObject/schema/create.js +30 -28
  22. package/commands/customObject/schema/delete.js +20 -20
  23. package/commands/customObject/schema/fetch-all.js +17 -24
  24. package/commands/customObject/schema/fetch.js +29 -24
  25. package/commands/customObject/schema/list.js +8 -17
  26. package/commands/customObject/schema/update.js +31 -29
  27. package/commands/customObject/schema.js +4 -1
  28. package/commands/customObject.js +10 -21
  29. package/commands/fetch.js +15 -30
  30. package/commands/filemanager/fetch.js +13 -25
  31. package/commands/filemanager/upload.js +47 -35
  32. package/commands/filemanager.js +4 -1
  33. package/commands/functions/deploy.js +34 -37
  34. package/commands/functions/list.js +9 -24
  35. package/commands/functions/server.js +13 -29
  36. package/commands/functions.js +4 -1
  37. package/commands/hubdb/clear.js +25 -21
  38. package/commands/hubdb/create.js +25 -22
  39. package/commands/hubdb/delete.js +19 -20
  40. package/commands/hubdb/fetch.js +15 -20
  41. package/commands/hubdb.js +4 -1
  42. package/commands/init.js +25 -13
  43. package/commands/lint.js +14 -23
  44. package/commands/list.js +19 -25
  45. package/commands/logs.js +22 -43
  46. package/commands/mv.js +21 -25
  47. package/commands/open.js +9 -7
  48. package/commands/project/create.js +13 -79
  49. package/commands/project/deploy.js +26 -30
  50. package/commands/project/listBuilds.js +6 -25
  51. package/commands/project/logs.js +81 -81
  52. package/commands/project/upload.js +68 -72
  53. package/commands/project/watch.js +103 -0
  54. package/commands/project.js +2 -0
  55. package/commands/remove.js +12 -20
  56. package/commands/sandbox/create.js +18 -13
  57. package/commands/secrets/addSecret.js +19 -22
  58. package/commands/secrets/deleteSecret.js +18 -21
  59. package/commands/secrets/listSecrets.js +10 -19
  60. package/commands/secrets/updateSecret.js +19 -22
  61. package/commands/secrets.js +4 -1
  62. package/commands/server.js +15 -6
  63. package/commands/{marketplaceValidate/validateTheme.js → theme/marketplace-validate.js} +26 -24
  64. package/commands/theme.js +5 -3
  65. package/commands/upload.js +66 -45
  66. package/commands/watch.js +33 -55
  67. package/lib/commonOpts.js +14 -11
  68. package/lib/enums/exitCodes.js +14 -0
  69. package/lib/links.js +0 -10
  70. package/lib/projects.js +57 -9
  71. package/lib/{createApiSamplePrompt.js → prompts/createApiSamplePrompt.js} +10 -11
  72. package/lib/{createFunctionPrompt.js → prompts/createFunctionPrompt.js} +27 -21
  73. package/lib/{createModulePrompt.js → prompts/createModulePrompt.js} +12 -9
  74. package/lib/prompts/createProjectPrompt.js +68 -0
  75. package/lib/{createTemplatePrompt.js → prompts/createTemplatePrompt.js} +7 -4
  76. package/lib/prompts/folderOverwritePrompt.js +17 -0
  77. package/lib/{prompts.js → prompts/personalAccessKeyPrompt.js} +25 -42
  78. package/lib/prompts/promptUtils.js +10 -0
  79. package/lib/prompts/sandboxesPrompt.js +24 -0
  80. package/lib/prompts/secretPrompt.js +25 -0
  81. package/lib/serverlessLogs.js +3 -2
  82. package/lib/ui.js +48 -0
  83. package/lib/validation.js +4 -3
  84. package/package.json +7 -7
  85. package/commands/app/deploy.js +0 -116
  86. package/commands/app.js +0 -14
  87. package/commands/create/project.js +0 -25
  88. package/lib/prompts/projects.js +0 -40
  89. package/lib/prompts/sandboxes.js +0 -22
  90. package/lib/secretPrompt.js +0 -22
package/commands/watch.js CHANGED
@@ -1,12 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
- const {
5
- watch,
6
- loadConfig,
7
- validateConfig,
8
- checkAndWarnGitInclusion,
9
- } = require('@hubspot/cli-lib');
4
+ const { watch } = require('@hubspot/cli-lib');
10
5
  const { getCwd } = require('@hubspot/cli-lib/path');
11
6
  const { logger } = require('@hubspot/cli-lib/logger');
12
7
 
@@ -15,42 +10,26 @@ const {
15
10
  addAccountOptions,
16
11
  addModeOptions,
17
12
  addUseEnvironmentOptions,
18
- setLogLevel,
19
13
  getAccountId,
20
14
  getMode,
21
15
  } = require('../lib/commonOpts');
22
- const { logDebugInfo } = require('../lib/debugInfo');
23
- const { validateAccount, validateMode } = require('../lib/validation');
16
+ const { validateMode, loadAndValidateOptions } = require('../lib/validation');
24
17
  const { trackCommandUsage } = require('../lib/usageTracking');
18
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
19
+
20
+ const i18nKey = 'cli.commands.watch';
21
+ const { EXIT_CODES } = require('../lib/enums/exitCodes');
25
22
 
26
23
  exports.command = 'watch <src> <dest>';
27
- exports.describe =
28
- 'Watch a directory on your computer for changes and upload the changed files to the HubSpot CMS';
24
+ exports.describe = i18n(`${i18nKey}.describe`);
29
25
 
30
26
  exports.handler = async options => {
31
- const {
32
- src,
33
- dest,
34
- config: configPath,
35
- remove,
36
- initialUpload,
37
- disableInitial,
38
- notify,
39
- } = options;
40
-
41
- setLogLevel(options);
42
- logDebugInfo(options);
43
- loadConfig(configPath, options);
44
- checkAndWarnGitInclusion();
45
-
46
- if (
47
- !(
48
- validateConfig() &&
49
- (await validateAccount(options)) &&
50
- validateMode(options)
51
- )
52
- ) {
53
- process.exit(1);
27
+ const { src, dest, remove, initialUpload, disableInitial, notify } = options;
28
+
29
+ await loadAndValidateOptions(options);
30
+
31
+ if (!validateMode(options)) {
32
+ process.exit(EXIT_CODES.ERROR);
54
33
  }
55
34
 
56
35
  const accountId = getAccountId(options);
@@ -60,32 +39,34 @@ exports.handler = async options => {
60
39
  try {
61
40
  const stats = fs.statSync(absoluteSrcPath);
62
41
  if (!stats.isDirectory()) {
63
- logger.log(`The "${src}" is not a path to a directory`);
42
+ logger.log(
43
+ i18n(`${i18nKey}.errors.invalidPath`, {
44
+ path: src,
45
+ })
46
+ );
64
47
  return;
65
48
  }
66
49
  } catch (e) {
67
- logger.log(`The "${src}" is not a path to a directory`);
50
+ logger.log(
51
+ i18n(`${i18nKey}.errors.invalidPath`, {
52
+ path: src,
53
+ })
54
+ );
68
55
  return;
69
56
  }
70
57
 
71
58
  if (!dest) {
72
- logger.log('A destination directory needs to be passed');
59
+ logger.log(i18n(`${i18nKey}.errors.destinationRequired`));
73
60
  return;
74
61
  }
75
62
 
76
63
  if (disableInitial) {
77
- logger.info(
78
- 'Passing the "--disable-initial" option is no longer necessary. Running "hs watch" no longer uploads the watched directory by default.'
79
- );
64
+ logger.info(i18n(`${i18nKey}.warnings.disableInitial`));
80
65
  } else {
81
- logger.info(
82
- `The "watch" command no longer uploads the watched directory when started. The directory "${src}" was not uploaded.`
83
- );
66
+ logger.info(i18n(`${i18nKey}.warnings.notUploaded`, { path: src }));
84
67
 
85
68
  if (!initialUpload) {
86
- logger.info(
87
- 'To upload the directory run "hs upload" beforehand or add the "--initial-upload" option when running "hs watch".'
88
- );
69
+ logger.info(i18n(`${i18nKey}.warnings.initialUpload`));
89
70
  }
90
71
  }
91
72
 
@@ -105,35 +86,32 @@ exports.builder = yargs => {
105
86
  addUseEnvironmentOptions(yargs, true);
106
87
 
107
88
  yargs.positional('src', {
108
- describe:
109
- 'Path to the local directory your files are in, relative to your current working directory',
89
+ describe: i18n(`${i18nKey}.positionals.src.describe`),
110
90
  type: 'string',
111
91
  });
112
92
  yargs.positional('dest', {
113
- describe: 'Path in HubSpot Design Tools. Can be a net new path',
93
+ describe: i18n(`${i18nKey}.positionals.dest.describe`),
114
94
  type: 'string',
115
95
  });
116
96
  yargs.option('remove', {
117
97
  alias: 'r',
118
- describe:
119
- 'Will cause watch to delete files in your HubSpot account that are not found locally.',
98
+ describe: i18n(`${i18nKey}.options.remove.describe`),
120
99
  type: 'boolean',
121
100
  });
122
101
  yargs.option('initial-upload', {
123
102
  alias: 'i',
124
- describe: 'Upload directory before watching for updates',
103
+ describe: i18n(`${i18nKey}.options.initialUpload.describe`),
125
104
  type: 'boolean',
126
105
  });
127
106
  yargs.option('disable-initial', {
128
107
  alias: 'd',
129
- describe: 'Disable the initial upload when watching a directory (default)',
108
+ describe: i18n(`${i18nKey}.options.disableInitial.describe`),
130
109
  type: 'boolean',
131
110
  hidden: true,
132
111
  });
133
112
  yargs.option('notify', {
134
113
  alias: 'n',
135
- describe:
136
- 'Log to specified file when a watch task is triggered and after workers have gone idle. Ex. --notify path/to/file',
114
+ describe: i18n(`${i18nKey}.options.notify.describe`),
137
115
  type: 'string',
138
116
  requiresArg: true,
139
117
  });
package/lib/commonOpts.js CHANGED
@@ -6,48 +6,51 @@ const {
6
6
  DEFAULT_MODE,
7
7
  Mode,
8
8
  } = require('@hubspot/cli-lib');
9
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
10
+
11
+ const i18nKey = 'cli.lib.commonOpts';
9
12
  const { LOG_LEVEL } = Logger;
10
13
 
11
14
  const addAccountOptions = program =>
12
15
  program.option('portal', {
13
16
  alias: ['p', 'account', 'a'],
14
- describe: 'HubSpot portal id or name from config',
17
+ describe: i18n(`${i18nKey}.options.portal.describe`),
15
18
  type: 'string',
16
19
  });
17
20
 
18
21
  const addConfigOptions = yargs =>
19
22
  yargs.option('config', {
20
23
  alias: 'c',
21
- describe: 'path to a config file',
24
+ describe: i18n(`${i18nKey}.options.config.describe`),
22
25
  type: 'string',
23
26
  });
24
27
 
25
28
  const addOverwriteOptions = yargs =>
26
29
  yargs.option('overwrite', {
27
30
  alias: 'o',
28
- describe: 'overwrite existing files',
31
+ describe: i18n(`${i18nKey}.options.overwrite.describe`),
29
32
  type: 'boolean',
30
33
  default: false,
31
34
  });
32
35
 
33
36
  const addModeOptions = (yargs, { read, write }) => {
34
37
  const modes = `<${Object.values(Mode).join(' | ')}>`;
35
- const help = read
36
- ? `read from ${modes}`
37
- : write
38
- ? `write to ${modes}`
39
- : `${modes}`;
40
38
 
41
39
  return yargs.option('mode', {
42
40
  alias: 'm',
43
- describe: help,
41
+ describe: i18n(
42
+ `${i18nKey}.options.modes.describe.${
43
+ read ? 'read' : write ? 'write' : 'default'
44
+ }`,
45
+ { modes }
46
+ ),
44
47
  type: 'string',
45
48
  });
46
49
  };
47
50
 
48
51
  const addTestingOptions = yargs =>
49
52
  yargs.option('qa', {
50
- describe: 'run command in qa mode',
53
+ describe: i18n(`${i18nKey}.options.qa.describe`),
51
54
  type: 'boolean',
52
55
  default: false,
53
56
  hidden: true,
@@ -55,7 +58,7 @@ const addTestingOptions = yargs =>
55
58
 
56
59
  const addUseEnvironmentOptions = yargs =>
57
60
  yargs.option('use-env', {
58
- describe: 'use environment variable config',
61
+ describe: i18n(`${i18nKey}.options.useEnv.describe`),
59
62
  type: 'boolean',
60
63
  default: false,
61
64
  });
@@ -0,0 +1,14 @@
1
+ /*
2
+ * 0: Successful run
3
+ * 1: Config problem or internal error
4
+ * 2: Warnings or validation issues
5
+ */
6
+ const EXIT_CODES = {
7
+ SUCCESS: 0,
8
+ ERROR: 1,
9
+ WARNING: 2,
10
+ };
11
+
12
+ module.exports = {
13
+ EXIT_CODES,
14
+ };
package/lib/links.js CHANGED
@@ -1,4 +1,3 @@
1
- const supportsHyperlinks = require('supports-hyperlinks');
2
1
  const { getEnv } = require('@hubspot/cli-lib/lib/config');
3
2
  const { ENVIRONMENTS } = require('@hubspot/cli-lib/lib/constants');
4
3
  const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
@@ -121,18 +120,9 @@ const openLink = (accountId, shortcut) => {
121
120
  logger.success(`We opened ${match.url} in your browser`);
122
121
  };
123
122
 
124
- const link = (linkText, url, options = {}) => {
125
- if (supportsHyperlinks.stdout) {
126
- return ['\u001B]8;;', url, '\u0007', linkText, '\u001B]8;;\u0007'].join('');
127
- } else {
128
- return options.fallback ? `${linkText}: ${url}` : linkText;
129
- }
130
- };
131
-
132
123
  module.exports = {
133
124
  getSiteLinks,
134
125
  getSiteLinksAsArray,
135
126
  logSiteLinks,
136
127
  openLink,
137
- link,
138
128
  };
package/lib/projects.js CHANGED
@@ -3,7 +3,6 @@ const path = require('path');
3
3
 
4
4
  const chalk = require('chalk');
5
5
  const findup = require('findup-sync');
6
- const { prompt } = require('inquirer');
7
6
  const Spinnies = require('spinnies');
8
7
  const { logger } = require('@hubspot/cli-lib/logger');
9
8
  const { getEnv } = require('@hubspot/cli-lib/lib/config');
@@ -11,7 +10,6 @@ const {
11
10
  createProject: createProjectTemplate,
12
11
  } = require('@hubspot/cli-lib/projects');
13
12
  const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls');
14
-
15
13
  const {
16
14
  ENVIRONMENTS,
17
15
  POLLING_DELAY,
@@ -30,6 +28,9 @@ const {
30
28
  ApiErrorContext,
31
29
  } = require('@hubspot/cli-lib/errorHandlers');
32
30
  const { getCwd } = require('@hubspot/cli-lib/path');
31
+ const { promptUser } = require('./prompts/promptUtils');
32
+ const { EXIT_CODES } = require('./enums/exitCodes');
33
+ const { uiLine, uiAccountDescription } = require('../lib/ui');
33
34
 
34
35
  const PROJECT_STRINGS = {
35
36
  BUILD: {
@@ -39,6 +40,10 @@ const PROJECT_STRINGS = {
39
40
  } in this project ...\n`,
40
41
  SUCCESS: name => `Built ${chalk.bold(name)}`,
41
42
  FAIL: name => `Failed to build ${chalk.bold(name)}`,
43
+ SUBTASK_FAIL: (taskId, name) =>
44
+ `Build #${taskId} failed because there was a problem\nbuilding ${chalk.bold(
45
+ name
46
+ )}`,
42
47
  },
43
48
  DEPLOY: {
44
49
  INITIALIZE: (name, numOfComponents) =>
@@ -47,6 +52,10 @@ const PROJECT_STRINGS = {
47
52
  } in this project ...\n`,
48
53
  SUCCESS: name => `Deployed ${chalk.bold(name)}`,
49
54
  FAIL: name => `Failed to deploy ${chalk.bold(name)}`,
55
+ SUBTASK_FAIL: (taskId, name) =>
56
+ `Deploy for build #${taskId} failed because there was a\nproblem deploying ${chalk.bold(
57
+ name
58
+ )}`,
50
59
  },
51
60
  };
52
61
 
@@ -60,7 +69,12 @@ const writeProjectConfig = (configPath, config) => {
60
69
  }
61
70
  };
62
71
 
63
- const getProjectConfig = async _dir => {
72
+ const getIsInProject = async _dir => {
73
+ const configPath = await getProjectConfigPath(_dir);
74
+ return !!configPath;
75
+ };
76
+
77
+ const getProjectConfigPath = async _dir => {
64
78
  const projectDir = _dir ? path.resolve(getCwd(), _dir) : getCwd();
65
79
 
66
80
  const configPath = findup(PROJECT_CONFIG_FILE, {
@@ -68,6 +82,11 @@ const getProjectConfig = async _dir => {
68
82
  nocase: true,
69
83
  });
70
84
 
85
+ return configPath;
86
+ };
87
+
88
+ const getProjectConfig = async _dir => {
89
+ const configPath = await getProjectConfigPath(_dir);
71
90
  if (!configPath) {
72
91
  return { projectConfig: null, projectDir: null };
73
92
  }
@@ -94,7 +113,7 @@ const createProjectConfig = async (projectPath, projectName, template) => {
94
113
  : `Found an existing project definition in ${projectDir}.`
95
114
  );
96
115
 
97
- const { shouldContinue } = await prompt([
116
+ const { shouldContinue } = await promptUser([
98
117
  {
99
118
  name: 'shouldContinue',
100
119
  message: () => {
@@ -147,21 +166,21 @@ const validateProjectConfig = (projectConfig, projectDir) => {
147
166
  logger.error(
148
167
  `Project config not found. Try running 'hs project create' first.`
149
168
  );
150
- process.exit(1);
169
+ process.exit(EXIT_CODES.ERROR);
151
170
  }
152
171
 
153
172
  if (!projectConfig.name || !projectConfig.srcDir) {
154
173
  logger.error(
155
174
  'Project config is missing required fields. Try running `hs project create`.'
156
175
  );
157
- process.exit(1);
176
+ process.exit(EXIT_CODES.ERROR);
158
177
  }
159
178
 
160
179
  if (!fs.existsSync(path.resolve(projectDir, projectConfig.srcDir))) {
161
180
  logger.error(
162
181
  `Project source directory '${projectConfig.srcDir}' could not be found in ${projectDir}.`
163
182
  );
164
- process.exit(1);
183
+ process.exit(EXIT_CODES.ERROR);
165
184
  }
166
185
  };
167
186
 
@@ -173,10 +192,12 @@ const ensureProjectExists = async (accountId, projectName, forceCreate) => {
173
192
  let shouldCreateProject = forceCreate;
174
193
 
175
194
  if (!shouldCreateProject) {
176
- const promptResult = await prompt([
195
+ const promptResult = await promptUser([
177
196
  {
178
197
  name: 'shouldCreateProject',
179
- message: `The project ${projectName} does not exist in ${accountId}. Would you like to create it?`,
198
+ message: `The project ${projectName} does not exist in ${uiAccountDescription(
199
+ accountId
200
+ )}. Would you like to create it?`,
180
201
  type: 'confirm',
181
202
  },
182
203
  ]);
@@ -260,6 +281,7 @@ const makeGetTaskStatus = taskType => {
260
281
  const spinnies = new Spinnies({
261
282
  succeedColor: 'white',
262
283
  failColor: 'white',
284
+ failPrefix: chalk.bold('!'),
263
285
  });
264
286
 
265
287
  spinnies.add('overallTaskStatus', { text: 'Beginning' });
@@ -330,6 +352,31 @@ const makeGetTaskStatus = taskType => {
330
352
  spinnies.fail('overallTaskStatus', {
331
353
  text: statusStrings.FAIL(taskName),
332
354
  });
355
+
356
+ const failedSubtask = subTaskStatus.filter(
357
+ subtask => subtask.status === 'FAILURE'
358
+ );
359
+
360
+ uiLine();
361
+ logger.log(
362
+ `${statusStrings.SUBTASK_FAIL(
363
+ buildId || taskId,
364
+ failedSubtask.length === 1
365
+ ? failedSubtask[0][statusText.SUBTASK_NAME_KEY]
366
+ : failedSubtask.length + ' components'
367
+ )}\n`
368
+ );
369
+ logger.log('See below for a summary of errors.');
370
+ uiLine();
371
+
372
+ failedSubtask.forEach(subTask => {
373
+ logger.log(
374
+ `\n--- ${chalk.bold(subTask[statusText.SUBTASK_NAME_KEY])} ${
375
+ statusText.STATUS_TEXT[subTask.status]
376
+ } with the following error ---`
377
+ );
378
+ logger.error(subTask.errorMessage);
379
+ });
333
380
  }
334
381
 
335
382
  clearInterval(pollInterval);
@@ -344,6 +391,7 @@ const makeGetTaskStatus = taskType => {
344
391
  module.exports = {
345
392
  writeProjectConfig,
346
393
  getProjectConfig,
394
+ getIsInProject,
347
395
  createProjectConfig,
348
396
  validateProjectConfig,
349
397
  showWelcomeMessage,
@@ -1,9 +1,12 @@
1
- const inquirer = require('inquirer');
1
+ const { promptUser } = require('./promptUtils');
2
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
3
+
4
+ const i18nKey = 'cli.lib.prompts.createApiSamplePrompt';
2
5
 
3
6
  const getSampleTypesPrompt = choices => ({
4
7
  type: 'rawlist',
5
8
  name: 'sampleType',
6
- message: 'Please, select API sample app',
9
+ message: i18n(`${i18nKey}.selectApiSampleApp`),
7
10
  choices: choices.map(choice => ({
8
11
  name: `${choice.name} - ${choice.description}`,
9
12
  value: choice.id,
@@ -13,7 +16,7 @@ const getSampleTypesPrompt = choices => ({
13
16
  if (input.length > 0) {
14
17
  resolve(true);
15
18
  }
16
- reject('Please select API sample app');
19
+ reject(i18n(`${i18nKey}.errors.apiSampleAppRequired`));
17
20
  });
18
21
  },
19
22
  });
@@ -21,7 +24,7 @@ const getSampleTypesPrompt = choices => ({
21
24
  const getLanguagesPrompt = choices => ({
22
25
  type: 'rawlist',
23
26
  name: 'sampleLanguage',
24
- message: "Please, select sample app's language",
27
+ message: i18n(`${i18nKey}.selectLanguage`),
25
28
  choices: choices.map(choice => ({
26
29
  name: choice,
27
30
  value: choice,
@@ -31,7 +34,7 @@ const getLanguagesPrompt = choices => ({
31
34
  if (input.length > 0) {
32
35
  resolve(true);
33
36
  }
34
- reject("Please select API sample app's language");
37
+ reject(i18n(`${i18nKey}.errors.languageRequired`));
35
38
  });
36
39
  },
37
40
  });
@@ -39,16 +42,12 @@ const getLanguagesPrompt = choices => ({
39
42
  const createApiSamplePrompt = async samplesConfig => {
40
43
  try {
41
44
  const { samples } = samplesConfig;
42
- const sampleTypeAnswer = await inquirer.prompt(
43
- getSampleTypesPrompt(samples)
44
- );
45
+ const sampleTypeAnswer = await promptUser(getSampleTypesPrompt(samples));
45
46
  const chosenSample = samples.find(
46
47
  sample => sample.id === sampleTypeAnswer.sampleType
47
48
  );
48
49
  const { languages } = chosenSample;
49
- const languagesAnswer = await inquirer.prompt(
50
- getLanguagesPrompt(languages)
51
- );
50
+ const languagesAnswer = await promptUser(getLanguagesPrompt(languages));
52
51
  return {
53
52
  ...sampleTypeAnswer,
54
53
  ...languagesAnswer,
@@ -1,66 +1,72 @@
1
- const inquirer = require('inquirer');
1
+ const { promptUser } = require('./promptUtils');
2
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
2
3
 
3
- const { STRING_WITH_NO_SPACES_REGEX } = require('./regex');
4
+ const { STRING_WITH_NO_SPACES_REGEX } = require('../regex');
5
+
6
+ const i18nKey = 'cli.lib.prompts.createFunctionPrompt';
4
7
 
5
8
  const FUNCTIONS_FOLDER_PROMPT = {
6
9
  name: 'functionsFolder',
7
- message: 'Name of the folder where your function will be created',
10
+ message: i18n(`${i18nKey}.enterFolder`),
8
11
  validate(val) {
9
12
  if (typeof val !== 'string') {
10
- return 'You entered an invalid name. Please try again.';
13
+ return i18n(`${i18nKey}.errors.invalid`);
11
14
  } else if (!val.length) {
12
- return 'The name may not be blank. Please try again.';
15
+ return i18n(`${i18nKey}.errors.blank`);
13
16
  } else if (!STRING_WITH_NO_SPACES_REGEX.test(val)) {
14
- return 'The name may not contain spaces. Please try again.';
17
+ return i18n(`${i18nKey}.errors.space`);
15
18
  }
16
19
  return true;
17
20
  },
18
21
  };
19
- const ENDPOINT_PATH_PROMPT = {
20
- name: 'endpointPath',
21
- message: 'Path portion of the URL created for the function',
22
+
23
+ const FUNCTION_FILENAME_PROMPT = {
24
+ name: 'filename',
25
+ message: i18n(`${i18nKey}.enterFilename`),
22
26
  validate(val) {
23
27
  if (typeof val !== 'string') {
24
- return 'You entered an invalid name. Please try again.';
28
+ return i18n(`${i18nKey}.errors.invalid`);
25
29
  } else if (!val.length) {
26
- return 'The name may not be blank. Please try again.';
30
+ return i18n(`${i18nKey}.errors.blank`);
27
31
  } else if (!STRING_WITH_NO_SPACES_REGEX.test(val)) {
28
- return 'The name may not contain spaces. Please try again.';
32
+ return i18n(`${i18nKey}.errors.space`);
29
33
  }
30
34
  return true;
31
35
  },
32
36
  };
37
+
33
38
  const ENDPOINT_METHOD_PROMPT = {
34
39
  type: 'list',
35
40
  name: 'endpointMethod',
36
- message: 'Select the HTTP method for the endpoint',
41
+ message: i18n(`${i18nKey}.selectEndpointMethod`),
37
42
  default: 'GET',
38
43
  choices: ['DELETE', 'GET', 'PATCH', 'POST', 'PUT'],
39
44
  };
40
- const FUNCTION_FILENAME_PROMPT = {
41
- name: 'filename',
42
- message: 'Name of the JavaScript file for your function',
45
+
46
+ const ENDPOINT_PATH_PROMPT = {
47
+ name: 'endpointPath',
48
+ message: i18n(`${i18nKey}.enterEndpointPath`),
43
49
  validate(val) {
44
50
  if (typeof val !== 'string') {
45
- return 'You entered an invalid name. Please try again.';
51
+ return i18n(`${i18nKey}.errors.invalid`);
46
52
  } else if (!val.length) {
47
- return 'The name may not be blank. Please try again.';
53
+ return i18n(`${i18nKey}.errors.blank`);
48
54
  } else if (!STRING_WITH_NO_SPACES_REGEX.test(val)) {
49
- return 'The name may not contain spaces. Please try again.';
55
+ return i18n(`${i18nKey}.errors.space`);
50
56
  }
51
57
  return true;
52
58
  },
53
59
  };
54
60
 
55
61
  function createFunctionPrompt() {
56
- const prompt = inquirer.createPromptModule();
57
- return prompt([
62
+ return promptUser([
58
63
  FUNCTIONS_FOLDER_PROMPT,
59
64
  FUNCTION_FILENAME_PROMPT,
60
65
  ENDPOINT_METHOD_PROMPT,
61
66
  ENDPOINT_PATH_PROMPT,
62
67
  ]);
63
68
  }
69
+
64
70
  module.exports = {
65
71
  createFunctionPrompt,
66
72
  };
@@ -1,13 +1,16 @@
1
- const inquirer = require('inquirer');
1
+ const { promptUser } = require('./promptUtils');
2
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
3
+
4
+ const i18nKey = 'cli.lib.prompts.createModulePrompt';
2
5
 
3
6
  const MODULE_LABEL_PROMPT = {
4
7
  name: 'moduleLabel',
5
- message: 'What should the module label be?',
8
+ message: i18n(`${i18nKey}.enterLabel`),
6
9
  validate(val) {
7
10
  if (typeof val !== 'string') {
8
- return 'You entered an invalid name. Please try again.';
11
+ return i18n(`${i18nKey}.errors.invalidLabel`);
9
12
  } else if (!val.length) {
10
- return 'The name may not be blank. Please try again.';
13
+ return i18n(`${i18nKey}.errors.labelRequired`);
11
14
  }
12
15
  return true;
13
16
  },
@@ -15,7 +18,7 @@ const MODULE_LABEL_PROMPT = {
15
18
  const CONTENT_TYPES_PROMPT = {
16
19
  type: 'checkbox',
17
20
  name: 'contentTypes',
18
- message: 'What types of content will this module be used in?',
21
+ message: i18n(`${i18nKey}.selectContentType`),
19
22
  default: ['PAGE'],
20
23
  choices: [
21
24
  { name: 'Page', value: 'PAGE' },
@@ -28,7 +31,7 @@ const CONTENT_TYPES_PROMPT = {
28
31
  if (input.length > 0) {
29
32
  resolve(true);
30
33
  }
31
- reject('Please select at least one content type for this module.');
34
+ reject(i18n(`${i18nKey}.errors.contentTypeRequired`));
32
35
  });
33
36
  },
34
37
  };
@@ -36,14 +39,14 @@ const CONTENT_TYPES_PROMPT = {
36
39
  const GLOBAL_PROMPT = {
37
40
  type: 'confirm',
38
41
  name: 'global',
39
- message: 'Is this a global module?',
42
+ message: i18n(`${i18nKey}.confirmGlobal`),
40
43
  default: false,
41
44
  };
42
45
 
43
46
  function createModulePrompt() {
44
- const prompt = inquirer.createPromptModule();
45
- return prompt([MODULE_LABEL_PROMPT, CONTENT_TYPES_PROMPT, GLOBAL_PROMPT]);
47
+ return promptUser([MODULE_LABEL_PROMPT, CONTENT_TYPES_PROMPT, GLOBAL_PROMPT]);
46
48
  }
49
+
47
50
  module.exports = {
48
51
  createModulePrompt,
49
52
  };