@hubspot/cli 3.0.9-beta.2 → 3.0.10-beta.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 (76) hide show
  1. package/README.md +6 -0
  2. package/bin/cli.js +3 -2
  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/app/deploy.js +22 -28
  7. package/commands/auth.js +30 -13
  8. package/commands/config/set/allowUsageTracking.js +15 -31
  9. package/commands/config/set/defaultAccount.js +22 -32
  10. package/commands/config/set/defaultMode.js +23 -42
  11. package/commands/config/set/httpTimeout.js +10 -28
  12. package/commands/config/set.js +4 -1
  13. package/commands/config.js +4 -1
  14. package/commands/create/api-sample.js +14 -12
  15. package/commands/create/module.js +19 -6
  16. package/commands/create/project.js +8 -1
  17. package/commands/create/template.js +19 -4
  18. package/commands/create.js +23 -8
  19. package/commands/customObject/create.js +22 -24
  20. package/commands/customObject/schema/create.js +30 -28
  21. package/commands/customObject/schema/delete.js +20 -20
  22. package/commands/customObject/schema/fetch-all.js +17 -24
  23. package/commands/customObject/schema/fetch.js +29 -24
  24. package/commands/customObject/schema/list.js +8 -17
  25. package/commands/customObject/schema/update.js +31 -29
  26. package/commands/customObject/schema.js +4 -1
  27. package/commands/customObject.js +10 -21
  28. package/commands/fetch.js +15 -30
  29. package/commands/filemanager/fetch.js +13 -25
  30. package/commands/filemanager/upload.js +47 -35
  31. package/commands/filemanager.js +4 -1
  32. package/commands/functions/deploy.js +34 -37
  33. package/commands/functions/list.js +9 -24
  34. package/commands/functions/server.js +13 -29
  35. package/commands/functions.js +4 -1
  36. package/commands/hubdb/clear.js +25 -21
  37. package/commands/hubdb/create.js +25 -22
  38. package/commands/hubdb/delete.js +19 -20
  39. package/commands/hubdb/fetch.js +15 -20
  40. package/commands/hubdb.js +4 -1
  41. package/commands/init.js +23 -11
  42. package/commands/lint.js +14 -23
  43. package/commands/list.js +19 -25
  44. package/commands/logs.js +41 -135
  45. package/commands/mv.js +21 -25
  46. package/commands/open.js +7 -5
  47. package/commands/project/create.js +111 -0
  48. package/commands/project/deploy.js +31 -39
  49. package/commands/project/listBuilds.js +160 -0
  50. package/commands/project/logs.js +192 -0
  51. package/commands/project/upload.js +125 -55
  52. package/commands/project.js +7 -8
  53. package/commands/remove.js +12 -20
  54. package/commands/sandbox/create.js +16 -11
  55. package/commands/secrets/addSecret.js +18 -21
  56. package/commands/secrets/deleteSecret.js +18 -21
  57. package/commands/secrets/listSecrets.js +10 -19
  58. package/commands/secrets/updateSecret.js +18 -21
  59. package/commands/secrets.js +4 -1
  60. package/commands/server.js +13 -5
  61. package/commands/{marketplaceValidate/validateTheme.js → theme/marketplace-validate.js} +26 -24
  62. package/commands/theme.js +5 -3
  63. package/commands/upload.js +66 -45
  64. package/commands/watch.js +33 -55
  65. package/lib/__tests__/serverlessLogs.js +8 -9
  66. package/lib/commonOpts.js +14 -11
  67. package/lib/enums/exitCodes.js +14 -0
  68. package/lib/projects.js +282 -230
  69. package/lib/prompts/projects.js +8 -5
  70. package/lib/prompts/sandboxes.js +5 -2
  71. package/lib/prompts.js +26 -27
  72. package/lib/serverlessLogs.js +11 -12
  73. package/lib/ui.js +48 -0
  74. package/lib/validation.js +2 -1
  75. package/package.json +6 -4
  76. package/commands/project/init.js +0 -108
@@ -0,0 +1,192 @@
1
+ const Spinnies = require('spinnies');
2
+ const { getCwd } = require('@hubspot/cli-lib/path');
3
+ const {
4
+ addAccountOptions,
5
+ addConfigOptions,
6
+ getAccountId,
7
+ addUseEnvironmentOptions,
8
+ } = require('../../lib/commonOpts');
9
+ const { trackCommandUsage } = require('../../lib/usageTracking');
10
+ const { logger } = require('@hubspot/cli-lib/logger');
11
+ const { outputLogs } = require('@hubspot/cli-lib/lib/logs');
12
+ const {
13
+ getProjectAppFunctionLogs,
14
+ getLatestProjectAppFunctionLog,
15
+ } = require('@hubspot/cli-lib/api/functions');
16
+ const { getProjectConfig } = require('../../lib/projects');
17
+ const { loadAndValidateOptions } = require('../../lib/validation');
18
+ const { tailLogs } = require('../../lib/serverlessLogs');
19
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
20
+
21
+ const i18nKey = 'cli.commands.project.subcommands.logs';
22
+ const { EXIT_CODES } = require('../../lib/enums/exitCodes');
23
+
24
+ const handleLogsError = (e, accountId, projectName, appPath, functionName) => {
25
+ if (e.statusCode === 404) {
26
+ logger.error(
27
+ i18n(`${i18nKey}.errors.logs`, {
28
+ accountId,
29
+ appPath,
30
+ functionName,
31
+ projectName,
32
+ })
33
+ );
34
+ }
35
+ };
36
+
37
+ const appFunctionLog = async (accountId, options) => {
38
+ const {
39
+ latest,
40
+ follow,
41
+ compact,
42
+ appPath,
43
+ functionName,
44
+ projectName,
45
+ } = options;
46
+
47
+ let logsResp;
48
+
49
+ if (follow) {
50
+ const spinnies = new Spinnies();
51
+
52
+ spinnies.add('tailLogs', {
53
+ text: i18n(`${i18nKey}.loading`),
54
+ });
55
+ const tailCall = after =>
56
+ getProjectAppFunctionLogs(accountId, functionName, projectName, appPath, {
57
+ after,
58
+ });
59
+ const fetchLatest = () => {
60
+ try {
61
+ return getLatestProjectAppFunctionLog(
62
+ accountId,
63
+ functionName,
64
+ projectName,
65
+ appPath
66
+ );
67
+ } catch (e) {
68
+ handleLogsError(e, accountId, projectName, appPath, functionName);
69
+ }
70
+ };
71
+
72
+ await tailLogs({
73
+ accountId,
74
+ compact,
75
+ spinnies,
76
+ tailCall,
77
+ fetchLatest,
78
+ });
79
+ } else if (latest) {
80
+ try {
81
+ logsResp = await getLatestProjectAppFunctionLog(
82
+ accountId,
83
+ functionName,
84
+ projectName,
85
+ appPath
86
+ );
87
+ } catch (e) {
88
+ handleLogsError(e, accountId, projectName, appPath, functionName);
89
+ }
90
+ } else {
91
+ try {
92
+ logsResp = await getProjectAppFunctionLogs(
93
+ accountId,
94
+ functionName,
95
+ projectName,
96
+ appPath,
97
+ {}
98
+ );
99
+ } catch (e) {
100
+ handleLogsError(e, accountId, projectName, appPath, functionName);
101
+ }
102
+ }
103
+
104
+ if (logsResp) {
105
+ return outputLogs(logsResp, options);
106
+ }
107
+ };
108
+
109
+ exports.command = 'logs [functionName]';
110
+ exports.describe = i18n(`${i18nKey}.describe`);
111
+
112
+ exports.handler = async options => {
113
+ await loadAndValidateOptions(options);
114
+
115
+ const { latest, functionName, appPath } = options;
116
+ let projectName = options.projectName;
117
+
118
+ if (!functionName) {
119
+ logger.error(i18n(`${i18nKey}.errors.functionNameRequired`));
120
+ process.exit(EXIT_CODES.ERROR);
121
+ } else if (!projectName) {
122
+ const projectConfig = await getProjectConfig(getCwd());
123
+ if (projectConfig && projectConfig.name) {
124
+ projectName = projectConfig.name;
125
+ } else {
126
+ logger.error(i18n(`${i18nKey}.errors.projectNameRequired`));
127
+ process.exit(EXIT_CODES.ERROR);
128
+ }
129
+ } else if (!appPath) {
130
+ logger.error(i18n(`${i18nKey}.errors.appPathRequired`));
131
+ process.exit(EXIT_CODES.ERROR);
132
+ }
133
+
134
+ const accountId = getAccountId(options);
135
+
136
+ trackCommandUsage('project-logs', { latest }, accountId);
137
+
138
+ appFunctionLog(accountId, { ...options, projectName });
139
+ };
140
+
141
+ exports.builder = yargs => {
142
+ yargs.positional('functionName', {
143
+ describe: i18n(`${i18nKey}.positionals.functionName.describe`),
144
+ type: 'string',
145
+ demandOption: true,
146
+ });
147
+ yargs
148
+ .options({
149
+ appPath: {
150
+ describe: i18n(`${i18nKey}.options.appPath.describe`),
151
+ type: 'string',
152
+ demandOption: true,
153
+ },
154
+ projectName: {
155
+ describe: i18n(`${i18nKey}.options.projectName.describe`),
156
+ type: 'string',
157
+ },
158
+ latest: {
159
+ alias: 'l',
160
+ describe: i18n(`${i18nKey}.options.latest.describe`),
161
+ type: 'boolean',
162
+ },
163
+ compact: {
164
+ describe: i18n(`${i18nKey}.options.compact.describe`),
165
+ type: 'boolean',
166
+ },
167
+ follow: {
168
+ alias: ['t', 'tail', 'f'],
169
+ describe: i18n(`${i18nKey}.options.follow.describe`),
170
+ type: 'boolean',
171
+ },
172
+ limit: {
173
+ alias: ['limit', 'n', 'max-count'],
174
+ describe: i18n(`${i18nKey}.options.limit.describe`),
175
+ type: 'number',
176
+ },
177
+ })
178
+ .conflicts('follow', 'limit');
179
+
180
+ yargs.example([
181
+ [
182
+ '$0 project logs my-function --appName="app" --projectName="my-project"',
183
+ i18n(`${i18nKey}.examples.default`),
184
+ ],
185
+ ]);
186
+
187
+ addConfigOptions(yargs, true);
188
+ addAccountOptions(yargs, true);
189
+ addUseEnvironmentOptions(yargs, true);
190
+
191
+ return yargs;
192
+ };
@@ -7,122 +7,182 @@ const Spinnies = require('spinnies');
7
7
  const {
8
8
  addAccountOptions,
9
9
  addConfigOptions,
10
- setLogLevel,
11
10
  getAccountId,
12
11
  addUseEnvironmentOptions,
13
12
  } = require('../../lib/commonOpts');
14
13
  const { trackCommandUsage } = require('../../lib/usageTracking');
15
- const { logDebugInfo } = require('../../lib/debugInfo');
16
- const {
17
- loadConfig,
18
- validateConfig,
19
- checkAndWarnGitInclusion,
20
- } = require('@hubspot/cli-lib');
21
14
  const {
22
15
  logApiErrorInstance,
23
16
  ApiErrorContext,
24
17
  } = require('@hubspot/cli-lib/errorHandlers');
18
+ const { uiLine, uiAccountDescription } = require('../../lib/ui');
25
19
  const { logger } = require('@hubspot/cli-lib/logger');
26
20
  const { uploadProject } = require('@hubspot/cli-lib/api/dfs');
27
21
  const { shouldIgnoreFile } = require('@hubspot/cli-lib/ignoreRules');
28
- const { getCwd } = require('@hubspot/cli-lib/path');
29
- const { validateAccount } = require('../../lib/validation');
22
+ const { loadAndValidateOptions } = require('../../lib/validation');
30
23
  const {
31
24
  getProjectConfig,
32
25
  validateProjectConfig,
33
26
  pollBuildStatus,
27
+ ensureProjectExists,
28
+ pollDeployStatus,
34
29
  } = require('../../lib/projects');
30
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
35
31
 
36
- const loadAndValidateOptions = async options => {
37
- setLogLevel(options);
38
- logDebugInfo(options);
39
- const { config: configPath } = options;
40
- loadConfig(configPath, options);
41
- checkAndWarnGitInclusion();
42
-
43
- if (!(validateConfig() && (await validateAccount(options)))) {
44
- process.exit(1);
45
- }
46
- };
32
+ const i18nKey = 'cli.commands.project.subcommands.upload';
33
+ const { EXIT_CODES } = require('../../lib/enums/exitCodes');
47
34
 
48
35
  exports.command = 'upload [path]';
49
36
  exports.describe = false;
50
37
 
51
38
  const uploadProjectFiles = async (accountId, projectName, filePath) => {
52
- const spinnies = new Spinnies();
39
+ const spinnies = new Spinnies({
40
+ succeedColor: 'white',
41
+ });
42
+ const accountIdentifier = uiAccountDescription(accountId);
53
43
 
54
44
  spinnies.add('upload', {
55
- text: `Uploading ${chalk.bold(projectName)} project files to ${chalk.bold(
56
- accountId
57
- )}`,
45
+ text: i18n(`${i18nKey}.loading.upload.add`, {
46
+ accountIdentifier,
47
+ projectName,
48
+ }),
58
49
  });
59
50
 
51
+ let buildId;
52
+
60
53
  try {
61
54
  const upload = await uploadProject(accountId, projectName, filePath);
62
55
 
56
+ buildId = upload.buildId;
57
+
63
58
  spinnies.succeed('upload', {
64
- text: `Uploaded ${chalk.bold(projectName)} project files to ${chalk.bold(
65
- accountId
66
- )}`,
59
+ text: i18n(`${i18nKey}.loading.upload.succeed`, {
60
+ accountIdentifier,
61
+ projectName,
62
+ }),
67
63
  });
68
64
 
69
65
  logger.debug(
70
- `Project "${projectName}" uploaded and build #${upload.buildId} created`
66
+ i18n(`${i18nKey}.debug.buildCreated`, {
67
+ buildId,
68
+ projectName,
69
+ })
71
70
  );
72
- await pollBuildStatus(accountId, projectName, upload.buildId);
73
71
  } catch (err) {
74
- if (err.statusCode === 404) {
75
- return logger.error(
76
- `Project '${projectName}' does not exist. Try running 'hs project init' first.`
77
- );
78
- }
79
-
80
72
  spinnies.fail('upload', {
81
- text: `Failed to upload ${chalk.bold(
82
- projectName
83
- )} project files to ${chalk.bold(accountId)}`,
73
+ text: i18n(`${i18nKey}.loading.upload.fail`, {
74
+ accountIdentifier,
75
+ projectName,
76
+ }),
84
77
  });
85
78
 
86
- logApiErrorInstance(err, {
87
- context: new ApiErrorContext({
79
+ logApiErrorInstance(
80
+ err,
81
+ new ApiErrorContext({
88
82
  accountId,
89
83
  projectName,
90
- }),
91
- });
84
+ })
85
+ );
86
+ process.exit(EXIT_CODES.ERROR);
92
87
  }
88
+
89
+ return { buildId };
93
90
  };
94
91
 
95
92
  exports.handler = async options => {
96
- loadAndValidateOptions(options);
93
+ await loadAndValidateOptions(options);
97
94
 
98
- const { path: projectPath } = options;
95
+ const { forceCreate, path: projectPath } = options;
99
96
  const accountId = getAccountId(options);
100
97
 
101
98
  trackCommandUsage('project-upload', { projectPath }, accountId);
102
99
 
103
- const cwd = projectPath ? path.resolve(getCwd(), projectPath) : getCwd();
104
- const projectConfig = await getProjectConfig(cwd);
100
+ const { projectConfig, projectDir } = await getProjectConfig(projectPath);
101
+
102
+ validateProjectConfig(projectConfig, projectDir);
105
103
 
106
- validateProjectConfig(projectConfig);
104
+ await ensureProjectExists(accountId, projectConfig.name, forceCreate);
107
105
 
108
106
  const tempFile = tmp.fileSync({ postfix: '.zip' });
109
107
 
110
- logger.debug(`Compressing build files to '${tempFile.name}'`);
108
+ logger.debug(
109
+ i18n(`${i18nKey}.debug.compressing`, {
110
+ path: tempFile.name,
111
+ })
112
+ );
111
113
 
112
114
  const output = fs.createWriteStream(tempFile.name);
113
115
  const archive = archiver('zip');
114
116
 
115
117
  output.on('close', async function() {
116
- logger.debug(`Project files compressed: ${archive.pointer()} bytes`);
118
+ let exitCode = EXIT_CODES.SUCCESS;
119
+ logger.debug(
120
+ i18n(`${i18nKey}.debug.compressed`, {
121
+ byteCount: archive.pointer(),
122
+ })
123
+ );
117
124
 
118
- await uploadProjectFiles(accountId, projectConfig.name, tempFile.name);
125
+ const { buildId } = await uploadProjectFiles(
126
+ accountId,
127
+ projectConfig.name,
128
+ tempFile.name
129
+ );
130
+
131
+ const {
132
+ isAutoDeployEnabled,
133
+ deployStatusTaskLocator,
134
+ status,
135
+ } = await pollBuildStatus(accountId, projectConfig.name, buildId);
136
+
137
+ if (status === 'FAILURE') {
138
+ exitCode = EXIT_CODES.ERROR;
139
+ return;
140
+ } else if (isAutoDeployEnabled && deployStatusTaskLocator) {
141
+ logger.log(
142
+ i18n(`${i18nKey}.logs.buildSucceededAutomaticallyDeploying`, {
143
+ accountIdentifier: uiAccountDescription(accountId),
144
+ buildId,
145
+ })
146
+ );
147
+ const { status } = await pollDeployStatus(
148
+ accountId,
149
+ projectConfig.name,
150
+ deployStatusTaskLocator.id,
151
+ buildId
152
+ );
153
+ if (status === 'FAILURE') {
154
+ exitCode = EXIT_CODES.ERROR;
155
+ }
156
+ } else {
157
+ uiLine();
158
+ logger.log(
159
+ chalk.bold(
160
+ i18n(`${i18nKey}.logs.buildSucceeded`, {
161
+ buildId,
162
+ })
163
+ )
164
+ );
165
+ logger.log(i18n(`${i18nKey}.logs.readyToGoLive`));
166
+ logger.log(
167
+ i18n(`${i18nKey}.logs.runCommand`, {
168
+ command: chalk.hex('f5c26b')('hs project deploy'),
169
+ })
170
+ );
171
+ uiLine();
172
+ }
119
173
 
120
174
  try {
121
175
  tempFile.removeCallback();
122
- logger.debug(`Cleaned up temporary file ${tempFile.name}`);
176
+ logger.debug(
177
+ i18n(`${i18nKey}.debug.cleanedUpTempFile`, {
178
+ path: tempFile.name,
179
+ })
180
+ );
123
181
  } catch (e) {
124
182
  logger.error(e);
125
183
  }
184
+
185
+ process.exit(exitCode);
126
186
  });
127
187
 
128
188
  archive.on('error', function(err) {
@@ -131,8 +191,10 @@ exports.handler = async options => {
131
191
 
132
192
  archive.pipe(output);
133
193
 
134
- archive.directory(path.resolve(cwd, projectConfig.srcDir), false, file =>
135
- shouldIgnoreFile(file.name) ? false : file
194
+ archive.directory(
195
+ path.resolve(projectDir, projectConfig.srcDir),
196
+ false,
197
+ file => (shouldIgnoreFile(file.name) ? false : file)
136
198
  );
137
199
 
138
200
  archive.finalize();
@@ -140,11 +202,19 @@ exports.handler = async options => {
140
202
 
141
203
  exports.builder = yargs => {
142
204
  yargs.positional('path', {
143
- describe: 'Path to a project folder',
205
+ describe: i18n(`${i18nKey}.positionals.path.describe`),
144
206
  type: 'string',
145
207
  });
146
208
 
147
- yargs.example([['$0 project upload myProjectFolder', 'Upload a project']]);
209
+ yargs.option('forceCreate', {
210
+ describe: i18n(`${i18nKey}.options.forceCreate.describe`),
211
+ type: 'boolean',
212
+ default: false,
213
+ });
214
+
215
+ yargs.example([
216
+ ['$0 project upload myProjectFolder', i18n(`${i18nKey}.examples.default`)],
217
+ ]);
148
218
 
149
219
  addConfigOptions(yargs, true);
150
220
  addAccountOptions(yargs, true);
@@ -1,24 +1,23 @@
1
- const {
2
- addConfigOptions,
3
- addAccountOptions,
4
- addOverwriteOptions,
5
- } = require('../lib/commonOpts');
1
+ const { addConfigOptions, addAccountOptions } = require('../lib/commonOpts');
6
2
  const deploy = require('./project/deploy');
7
- const init = require('./project/init');
3
+ const create = require('./project/create');
8
4
  const upload = require('./project/upload');
5
+ const listBuilds = require('./project/listBuilds');
6
+ const logs = require('./project/logs');
9
7
 
10
8
  exports.command = 'project';
11
9
  exports.describe = false; //'Commands for working with projects';
12
10
 
13
11
  exports.builder = yargs => {
14
- addOverwriteOptions(yargs, true);
15
12
  addConfigOptions(yargs, true);
16
13
  addAccountOptions(yargs, true);
17
14
 
18
15
  // TODO: deploy must be updated
19
16
  yargs.command(deploy).demandCommand(1, '');
20
- yargs.command(init).demandCommand(0, '');
17
+ yargs.command(create).demandCommand(0, '');
21
18
  yargs.command(upload).demandCommand(0, '');
19
+ yargs.command(listBuilds).demandCommand(0, '');
20
+ yargs.command(logs).demandCommand(1, '');
22
21
 
23
22
  return yargs;
24
23
  };
@@ -1,9 +1,4 @@
1
1
  const { deleteFile } = require('@hubspot/cli-lib/api/fileMapper');
2
- const {
3
- loadConfig,
4
- validateConfig,
5
- checkAndWarnGitInclusion,
6
- } = require('@hubspot/cli-lib');
7
2
  const { logger } = require('@hubspot/cli-lib/logger');
8
3
  const {
9
4
  logApiErrorInstance,
@@ -14,26 +9,21 @@ const {
14
9
  addConfigOptions,
15
10
  addAccountOptions,
16
11
  addUseEnvironmentOptions,
17
- setLogLevel,
18
12
  getAccountId,
19
13
  } = require('../lib/commonOpts');
20
- const { logDebugInfo } = require('../lib/debugInfo');
21
- const { validateAccount } = require('../lib/validation');
14
+ const { loadAndValidateOptions } = require('../lib/validation');
22
15
  const { trackCommandUsage } = require('../lib/usageTracking');
16
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
17
+
18
+ const i18nKey = 'cli.commands.remove';
23
19
 
24
20
  exports.command = 'remove <path>';
25
- exports.describe = 'Delete a file or folder from HubSpot';
21
+ exports.describe = i18n(`${i18nKey}.describe`);
26
22
 
27
23
  exports.handler = async options => {
28
- setLogLevel(options);
29
- logDebugInfo(options);
30
- const { config: configPath, path: hsPath } = options;
31
- loadConfig(configPath, options);
32
- checkAndWarnGitInclusion();
24
+ const { path: hsPath } = options;
33
25
 
34
- if (!(validateConfig() && (await validateAccount(options)))) {
35
- process.exit(1);
36
- }
26
+ await loadAndValidateOptions(options);
37
27
 
38
28
  const accountId = getAccountId(options);
39
29
 
@@ -41,9 +31,11 @@ exports.handler = async options => {
41
31
 
42
32
  try {
43
33
  await deleteFile(accountId, hsPath);
44
- logger.log(`Deleted "${hsPath}" from account ${accountId}`);
34
+ logger.log(i18n(`${i18nKey}.deleted`, { accountId, path: hsPath }));
45
35
  } catch (error) {
46
- logger.error(`Deleting "${hsPath}" from account ${accountId} failed`);
36
+ logger.error(
37
+ i18n(`${i18nKey}.errors.deleteFailed`, { accountId, path: hsPath })
38
+ );
47
39
  logApiErrorInstance(
48
40
  error,
49
41
  new ApiErrorContext({
@@ -59,7 +51,7 @@ exports.builder = yargs => {
59
51
  addAccountOptions(yargs, true);
60
52
  addUseEnvironmentOptions(yargs, true);
61
53
  yargs.positional('path', {
62
- describe: 'Remote hubspot path',
54
+ describe: i18n(`${i18nKey}.positionals.path.describe`),
63
55
  type: 'string',
64
56
  });
65
57
  return yargs;
@@ -10,12 +10,15 @@ const { logger } = require('@hubspot/cli-lib/logger');
10
10
  const { createSandbox } = require('@hubspot/cli-lib/sandboxes');
11
11
  const { loadAndValidateOptions } = require('../../lib/validation');
12
12
  const { createSandbox: prompt } = require('../../lib/prompts/sandboxes');
13
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
14
+
15
+ const i18nKey = 'cli.commands.sandbox.subcommands.create';
13
16
 
14
17
  exports.command = 'create [name]';
15
18
  exports.describe = false;
16
19
 
17
20
  exports.handler = async options => {
18
- loadAndValidateOptions(options);
21
+ await loadAndValidateOptions(options);
19
22
 
20
23
  const { name } = options;
21
24
  const accountId = getAccountId(options);
@@ -29,31 +32,33 @@ exports.handler = async options => {
29
32
 
30
33
  const sandboxName = name || namePrompt.name;
31
34
 
32
- logger.debug(`Creating sandbox '${sandboxName}'`);
35
+ logger.debug(
36
+ i18n(`${i18nKey}.debug.creating`, {
37
+ name: sandboxName,
38
+ })
39
+ );
33
40
 
34
41
  return createSandbox(accountId, sandboxName).then(
35
42
  ({ name, sandboxHubId }) => {
36
43
  logger.success(
37
- `Sandbox '${name}' with portalId '${sandboxHubId}' created successfully.`
38
- );
39
- logger.info(
40
- `Run 'hs auth' to authenticate with the new sandbox account.`
44
+ i18n(`${i18nKey}.describe`, {
45
+ name,
46
+ sandboxHubId,
47
+ })
41
48
  );
49
+ logger.info(i18n(`${i18nKey}.info.auth`));
42
50
  }
43
51
  );
44
52
  };
45
53
 
46
54
  exports.builder = yargs => {
47
55
  yargs.positional('name', {
48
- describe: 'Name to use for created sandbox',
56
+ describe: i18n(`${i18nKey}.positionals.name.describe`),
49
57
  type: 'string',
50
58
  });
51
59
 
52
60
  yargs.example([
53
- [
54
- '$0 sandbox create MySandboxAccount',
55
- 'Create a sandbox account named MySandboxAccount.',
56
- ],
61
+ ['$0 sandbox create MySandboxAccount', i18n(`${i18nKey}.examples.default`)],
57
62
  ]);
58
63
 
59
64
  addConfigOptions(yargs, true);
@@ -1,8 +1,3 @@
1
- const {
2
- loadConfig,
3
- validateConfig,
4
- checkAndWarnGitInclusion,
5
- } = require('@hubspot/cli-lib');
6
1
  const { logger } = require('@hubspot/cli-lib/logger');
7
2
  const {
8
3
  logServerlessFunctionApiErrorInstance,
@@ -10,33 +5,28 @@ const {
10
5
  } = require('@hubspot/cli-lib/errorHandlers');
11
6
  const { addSecret } = require('@hubspot/cli-lib/api/secrets');
12
7
 
13
- const { validateAccount } = require('../../lib/validation');
8
+ const { loadAndValidateOptions } = require('../../lib/validation');
14
9
  const { trackCommandUsage } = require('../../lib/usageTracking');
15
10
 
16
11
  const {
17
12
  addConfigOptions,
18
13
  addAccountOptions,
19
14
  addUseEnvironmentOptions,
20
- setLogLevel,
21
15
  getAccountId,
22
16
  } = require('../../lib/commonOpts');
23
- const { logDebugInfo } = require('../../lib/debugInfo');
24
17
  const { secretValuePrompt } = require('../../lib/secretPrompt');
18
+ const { i18n } = require('@hubspot/cli-lib/lib/lang');
19
+
20
+ const i18nKey = 'cli.commands.secrets.subcommands.add';
25
21
 
26
22
  exports.command = 'add <name>';
27
- exports.describe = 'Add a HubSpot secret';
23
+ exports.describe = i18n(`${i18nKey}.describe`);
28
24
 
29
25
  exports.handler = async options => {
30
- const { config: configPath, name: secretName } = options;
26
+ const { name: secretName } = options;
31
27
 
32
- setLogLevel(options);
33
- logDebugInfo(options);
34
- loadConfig(configPath, options);
35
- checkAndWarnGitInclusion();
28
+ await loadAndValidateOptions(options);
36
29
 
37
- if (!(validateConfig() && (await validateAccount(options)))) {
38
- process.exit(1);
39
- }
40
30
  const accountId = getAccountId(options);
41
31
  trackCommandUsage('secrets-add', {}, accountId);
42
32
 
@@ -44,11 +34,18 @@ exports.handler = async options => {
44
34
  const { secretValue } = await secretValuePrompt();
45
35
 
46
36
  await addSecret(accountId, secretName, secretValue);
47
- logger.log(
48
- `The secret "${secretName}" was added to the HubSpot account: ${accountId}`
37
+ logger.success(
38
+ i18n(`${i18nKey}.success.add`, {
39
+ accountId,
40
+ secretName,
41
+ })
49
42
  );
50
43
  } catch (e) {
51
- logger.error(`The secret "${secretName}" was not added`);
44
+ logger.error(
45
+ i18n(`${i18nKey}.errors.add`, {
46
+ secretName,
47
+ })
48
+ );
52
49
  await logServerlessFunctionApiErrorInstance(
53
50
  accountId,
54
51
  e,
@@ -65,7 +62,7 @@ exports.builder = yargs => {
65
62
  addAccountOptions(yargs, true);
66
63
  addUseEnvironmentOptions(yargs, true);
67
64
  yargs.positional('name', {
68
- describe: 'Name of the secret',
65
+ describe: i18n(`${i18nKey}.positionals.name.describe`),
69
66
  type: 'string',
70
67
  });
71
68
  return yargs;