@hubspot/cli 4.2.1-beta.3 → 5.0.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.
package/bin/cli.js CHANGED
@@ -42,7 +42,11 @@ const cmsCommand = require('../commands/cms');
42
42
  const feedbackCommand = require('../commands/feedback');
43
43
  const { EXIT_CODES } = require('../lib/enums/exitCodes');
44
44
 
45
- const notifier = updateNotifier({ pkg: { ...pkg, name: '@hubspot/cli' } });
45
+ const notifier = updateNotifier({
46
+ pkg: { ...pkg, name: '@hubspot/cli' },
47
+ distTag: 'latest',
48
+ shouldNotifyInNpmScript: true,
49
+ });
46
50
 
47
51
  const i18nKey = 'cli.commands.generalErrors';
48
52
 
@@ -51,7 +55,6 @@ const CLI_UPGRADE_MESSAGE =
51
55
  '\n\nTo upgrade, run:\n\nnpm uninstall -g @hubspot/cms-cli\nand npm install -g @hubspot/cli';
52
56
 
53
57
  notifier.notify({
54
- shouldNotifyInNpmScript: true,
55
58
  message: pkg.name === '@hubspot/cms-cli' ? CLI_UPGRADE_MESSAGE : null,
56
59
  });
57
60
 
@@ -1,28 +1,24 @@
1
- const chalk = require('chalk');
2
1
  const { addConfigOptions, addAccountOptions } = require('../lib/commonOpts');
3
2
  const schemaCommand = require('./customObject/schema');
4
3
  const createCommand = require('./customObject/create');
5
4
  const { i18n } = require('../lib/lang');
6
5
  const { logger } = require('@hubspot/cli-lib/logger');
7
- const { uiBetaWarning } = require('../lib/ui');
6
+ const { uiBetaTag, uiLink } = require('../lib/ui');
8
7
 
9
8
  const i18nKey = 'cli.commands.customObject';
10
9
 
11
10
  exports.command = ['custom-object', 'custom', 'co'];
12
- exports.describe = i18n(`${i18nKey}.describe`);
11
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
13
12
 
14
13
  const logBetaMessage = () => {
15
- uiBetaWarning(() => {
16
- logger.log(chalk.reset.yellow(i18n(`${i18nKey}.betaMessage`)));
17
- logger.log(
18
- chalk.reset.yellow(
19
- i18n(`${i18nKey}.seeMoreLink`, {
20
- link:
21
- 'https://developers.hubspot.com/docs/api/crm/crm-custom-objects',
22
- })
23
- )
24
- );
25
- });
14
+ uiBetaTag(i18n(`${i18nKey}.betaMessage`));
15
+ logger.log(
16
+ uiLink(
17
+ i18n(`${i18nKey}.seeMoreLink`),
18
+ 'https://developers.hubspot.com/docs/api/crm/crm-custom-objects'
19
+ )
20
+ );
21
+ logger.log();
26
22
  };
27
23
 
28
24
  exports.builder = yargs => {
package/commands/mv.js CHANGED
@@ -15,6 +15,7 @@ const { trackCommandUsage } = require('../lib/usageTracking');
15
15
  const { isPathFolder } = require('../lib/filesystem');
16
16
  const { loadAndValidateOptions } = require('../lib/validation');
17
17
  const { i18n } = require('../lib/lang');
18
+ const { uiBetaTag } = require('../lib/ui');
18
19
 
19
20
  const i18nKey = 'cli.commands.mv';
20
21
 
@@ -28,7 +29,7 @@ const getCorrectedDestPath = (srcPath, destPath) => {
28
29
  };
29
30
 
30
31
  exports.command = 'mv <srcPath> <destPath>';
31
- exports.describe = i18n(`${i18nKey}.describe`);
32
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
32
33
 
33
34
  exports.handler = async options => {
34
35
  await loadAndValidateOptions(options);
@@ -7,11 +7,12 @@ const { i18n } = require('../../lib/lang');
7
7
  const { projectAddPrompt } = require('../../lib/prompts/projectAddPrompt');
8
8
  const { createProjectComponent } = require('../../lib/projects');
9
9
  const { loadAndValidateOptions } = require('../../lib/validation');
10
+ const { uiBetaTag } = require('../../lib/ui');
10
11
 
11
12
  const i18nKey = 'cli.commands.project.subcommands.add';
12
13
 
13
14
  exports.command = 'add';
14
- exports.describe = i18n(`${i18nKey}.describe`);
15
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
15
16
 
16
17
  exports.handler = async options => {
17
18
  await loadAndValidateOptions(options);
@@ -14,13 +14,13 @@ const {
14
14
  } = require('../../lib/prompts/createProjectPrompt');
15
15
  const { createProjectConfig } = require('../../lib/projects');
16
16
  const { i18n } = require('../../lib/lang');
17
- const { uiFeatureHighlight } = require('../../lib/ui');
17
+ const { uiBetaTag, uiFeatureHighlight } = require('../../lib/ui');
18
18
  const { logger } = require('@hubspot/cli-lib/logger');
19
19
 
20
20
  const i18nKey = 'cli.commands.project.subcommands.create';
21
21
 
22
22
  exports.command = 'create';
23
- exports.describe = i18n(`${i18nKey}.describe`);
23
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
24
24
 
25
25
  exports.handler = async options => {
26
26
  await loadAndValidateOptions(options);
@@ -38,15 +38,14 @@ exports.handler = async options => {
38
38
  await createProjectConfig(
39
39
  path.resolve(getCwd(), options.location || location),
40
40
  options.name || name,
41
- options.template || template,
41
+ template || { path: options.template },
42
42
  options.templateSource
43
43
  );
44
44
 
45
45
  logger.log('');
46
46
  logger.log(chalk.bold(i18n(`${i18nKey}.logs.welcomeMessage`)));
47
47
  uiFeatureHighlight([
48
- 'projectUploadCommand',
49
- 'projectDeployCommand',
48
+ 'projectDevCommand',
50
49
  'projectHelpCommand',
51
50
  'feedbackCommand',
52
51
  ]);
@@ -1,3 +1,4 @@
1
+ const chalk = require('chalk');
1
2
  const {
2
3
  addAccountOptions,
3
4
  addConfigOptions,
@@ -16,13 +17,15 @@ const { getProjectConfig, pollDeployStatus } = require('../../lib/projects');
16
17
  const { projectNamePrompt } = require('../../lib/prompts/projectNamePrompt');
17
18
  const { buildIdPrompt } = require('../../lib/prompts/buildIdPrompt');
18
19
  const { i18n } = require('../../lib/lang');
20
+ const { uiBetaTag } = require('../../lib/ui');
19
21
  const { getAccountConfig } = require('@hubspot/cli-lib');
20
22
 
21
23
  const i18nKey = 'cli.commands.project.subcommands.deploy';
22
24
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
25
+ const { uiCommandReference, uiAccountDescription } = require('../../lib/ui');
23
26
 
24
27
  exports.command = 'deploy [--project] [--buildId]';
25
- exports.describe = i18n(`${i18nKey}.describe`);
28
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
26
29
 
27
30
  exports.handler = async options => {
28
31
  await loadAndValidateOptions(options);
@@ -98,6 +101,15 @@ exports.handler = async options => {
98
101
  buildIdToDeploy
99
102
  );
100
103
  } catch (e) {
104
+ if (e.statusCode === 404) {
105
+ logger.error(
106
+ i18n(`${i18nKey}.errors.projectNotFound`, {
107
+ projectName: chalk.bold(projectName),
108
+ accountIdentifier: uiAccountDescription(accountId),
109
+ command: uiCommandReference('hs project upload'),
110
+ })
111
+ );
112
+ }
101
113
  if (e.statusCode === 400) {
102
114
  logger.error(e.error.message);
103
115
  } else {
@@ -25,7 +25,7 @@ const {
25
25
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
26
26
  const {
27
27
  uiAccountDescription,
28
- uiBetaMessage,
28
+ uiBetaTag,
29
29
  uiCommandReference,
30
30
  uiLine,
31
31
  } = require('../../lib/ui');
@@ -66,7 +66,7 @@ const {
66
66
  const i18nKey = 'cli.commands.project.subcommands.dev';
67
67
 
68
68
  exports.command = 'dev [--account]';
69
- exports.describe = i18n(`${i18nKey}.describe`);
69
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
70
70
 
71
71
  exports.handler = async options => {
72
72
  await loadAndValidateOptions(options);
@@ -78,10 +78,7 @@ exports.handler = async options => {
78
78
 
79
79
  const { projectConfig, projectDir } = await getProjectConfig();
80
80
 
81
- if (!options.debug) {
82
- console.clear();
83
- }
84
- uiBetaMessage(i18n(`${i18nKey}.logs.betaMessage`));
81
+ uiBetaTag(i18n(`${i18nKey}.logs.betaMessage`));
85
82
 
86
83
  if (!projectConfig) {
87
84
  logger.error(i18n(`${i18nKey}.errors.noProjectConfig`));
@@ -203,19 +200,18 @@ exports.handler = async options => {
203
200
  );
204
201
 
205
202
  let deployedBuild;
203
+ let isGithubLinked;
206
204
 
207
205
  if (projectExists) {
208
206
  const project = await fetchProject(targetAccountId, projectConfig.name);
209
207
  deployedBuild = project.deployedBuild;
208
+ isGithubLinked =
209
+ project.sourceIntegration &&
210
+ project.sourceIntegration.source === 'GITHUB';
210
211
  }
211
212
 
212
213
  SpinniesManager.init();
213
214
 
214
- if (!options.debug) {
215
- console.clear();
216
- }
217
- uiBetaMessage(i18n(`${i18nKey}.logs.betaMessage`));
218
-
219
215
  if (!projectExists) {
220
216
  // Create the project without prompting if this is a newly created sandbox
221
217
  let shouldCreateProject = createNewSandbox;
@@ -242,13 +238,14 @@ exports.handler = async options => {
242
238
  if (shouldCreateProject) {
243
239
  await showPlatformVersionWarning(accountId, projectConfig);
244
240
 
241
+ SpinniesManager.add('createProject', {
242
+ text: i18n(`${i18nKey}.status.creatingProject`, {
243
+ accountIdentifier: uiAccountDescription(targetAccountId),
244
+ projectName: projectConfig.name,
245
+ }),
246
+ });
247
+
245
248
  try {
246
- SpinniesManager.add('createProject', {
247
- text: i18n(`${i18nKey}.status.creatingProject`, {
248
- accountIdentifier: uiAccountDescription(targetAccountId),
249
- projectName: projectConfig.name,
250
- }),
251
- });
252
249
  await createProject(targetAccountId, projectConfig.name);
253
250
  SpinniesManager.succeed('createProject', {
254
251
  text: i18n(`${i18nKey}.status.createdProject`, {
@@ -258,6 +255,7 @@ exports.handler = async options => {
258
255
  succeedColor: 'white',
259
256
  });
260
257
  } catch (err) {
258
+ SpinniesManager.fail('createProject');
261
259
  logger.log(i18n(`${i18nKey}.status.failedToCreateProject`));
262
260
  process.exit(EXIT_CODES.ERROR);
263
261
  }
@@ -317,7 +315,7 @@ exports.handler = async options => {
317
315
 
318
316
  logger.log();
319
317
  failedSubTasks.forEach(failedSubTask => {
320
- console.log(failedSubTask.errorMessage);
318
+ console.error(failedSubTask.errorMessage);
321
319
  });
322
320
  logger.log();
323
321
 
@@ -333,6 +331,7 @@ exports.handler = async options => {
333
331
  projectConfig,
334
332
  projectDir,
335
333
  targetAccountId,
334
+ isGithubLinked,
336
335
  });
337
336
 
338
337
  await LocalDev.start();
@@ -23,12 +23,13 @@ const {
23
23
  downloadProjectPrompt,
24
24
  } = require('../../lib/prompts/downloadProjectPrompt');
25
25
  const { i18n } = require('../../lib/lang');
26
+ const { uiBetaTag } = require('../../lib/ui');
26
27
 
27
28
  const i18nKey = 'cli.commands.project.subcommands.download';
28
29
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
29
30
 
30
31
  exports.command = 'download [--project]';
31
- exports.describe = i18n(`${i18nKey}.describe`);
32
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
32
33
 
33
34
  exports.handler = async options => {
34
35
  await loadAndValidateOptions(options);
@@ -22,7 +22,7 @@ const {
22
22
  getTableHeader,
23
23
  } = require('@hubspot/cli-lib/lib/table');
24
24
  const { getCwd } = require('@hubspot/cli-lib/path');
25
- const { uiLink } = require('../../lib/ui');
25
+ const { uiBetaTag, uiLink } = require('../../lib/ui');
26
26
  const { loadAndValidateOptions } = require('../../lib/validation');
27
27
  const {
28
28
  getProjectConfig,
@@ -35,7 +35,7 @@ const { promptUser } = require('../../lib/prompts/promptUtils');
35
35
  const i18nKey = 'cli.commands.project.subcommands.listBuilds';
36
36
 
37
37
  exports.command = 'list-builds [path]';
38
- exports.describe = i18n(`${i18nKey}.describe`);
38
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
39
39
 
40
40
  exports.handler = async options => {
41
41
  await loadAndValidateOptions(options);
@@ -32,7 +32,7 @@ const {
32
32
  // } = require('@hubspot/cli-lib/api/results');
33
33
  const { ensureProjectExists } = require('../../lib/projects');
34
34
  const { loadAndValidateOptions } = require('../../lib/validation');
35
- const { uiLine, uiLink } = require('../../lib/ui');
35
+ const { uiBetaTag, uiLine, uiLink } = require('../../lib/ui');
36
36
  const { projectLogsPrompt } = require('../../lib/prompts/projectsLogsPrompt');
37
37
  // const { tailLogs } = require('../../lib/serverlessLogs');
38
38
  const { i18n } = require('../../lib/lang');
@@ -136,7 +136,7 @@ const getPrivateAppsUrl = accountId => {
136
136
  // };
137
137
 
138
138
  exports.command = 'logs [--project] [--app] [--function] [--endpoint]';
139
- exports.describe = i18n(`${i18nKey}.describe`);
139
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
140
140
 
141
141
  exports.handler = async options => {
142
142
  await loadAndValidateOptions(options);
@@ -16,12 +16,13 @@ const {
16
16
  ensureProjectExists,
17
17
  } = require('../../lib/projects');
18
18
  const { projectNamePrompt } = require('../../lib/prompts/projectNamePrompt');
19
+ const { uiBetaTag } = require('../../lib/ui');
19
20
  const { EXIT_CODES } = require('../../lib/enums/exitCodes');
20
21
 
21
22
  const i18nKey = 'cli.commands.project.subcommands.open';
22
23
 
23
24
  exports.command = 'open [--project]';
24
- exports.describe = i18n(`${i18nKey}.describe`);
25
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
25
26
 
26
27
  exports.handler = async options => {
27
28
  await loadAndValidateOptions(options);
@@ -6,7 +6,7 @@ const {
6
6
  } = require('../../lib/commonOpts');
7
7
  const chalk = require('chalk');
8
8
  const { logger } = require('@hubspot/cli-lib/logger');
9
- const { uiLine } = require('../../lib/ui');
9
+ const { uiBetaTag, uiLine } = require('../../lib/ui');
10
10
  const { trackCommandUsage } = require('../../lib/usageTracking');
11
11
  const { loadAndValidateOptions } = require('../../lib/validation');
12
12
  const {
@@ -33,7 +33,7 @@ const { EXIT_CODES } = require('../../lib/enums/exitCodes');
33
33
  const i18nKey = 'cli.commands.project.subcommands.upload';
34
34
 
35
35
  exports.command = 'upload [path]';
36
- exports.describe = i18n(`${i18nKey}.describe`);
36
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
37
37
 
38
38
  exports.handler = async options => {
39
39
  await loadAndValidateOptions(options);
@@ -13,6 +13,7 @@ const {
13
13
  addUseEnvironmentOptions,
14
14
  } = require('../../lib/commonOpts');
15
15
  const { trackCommandUsage } = require('../../lib/usageTracking');
16
+ const { uiBetaTag } = require('../../lib/ui');
16
17
  const {
17
18
  ensureProjectExists,
18
19
  getProjectConfig,
@@ -34,7 +35,7 @@ const { handleKeypress, handleExit } = require('@hubspot/cli-lib/lib/process');
34
35
  const i18nKey = 'cli.commands.project.subcommands.watch';
35
36
 
36
37
  exports.command = 'watch [path]';
37
- exports.describe = i18n(`${i18nKey}.describe`);
38
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
38
39
 
39
40
  const handleBuildStatus = async (accountId, projectName, buildId) => {
40
41
  const {
@@ -1,5 +1,6 @@
1
1
  const { addConfigOptions, addAccountOptions } = require('../lib/commonOpts');
2
2
  const { i18n } = require('../lib/lang');
3
+ const { uiBetaTag } = require('../lib/ui');
3
4
  const deploy = require('./project/deploy');
4
5
  const create = require('./project/create');
5
6
  const upload = require('./project/upload');
@@ -14,7 +15,7 @@ const add = require('./project/add');
14
15
  const i18nKey = 'cli.commands.project';
15
16
 
16
17
  exports.command = 'project';
17
- exports.describe = i18n(`${i18nKey}.describe`);
18
+ exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
18
19
 
19
20
  exports.builder = yargs => {
20
21
  addConfigOptions(yargs, true);
@@ -41,7 +41,7 @@ exports.handler = async options => {
41
41
  secretName,
42
42
  })
43
43
  );
44
- logger.log(i18n(`${i18nKey}.success.updateReupload`));
44
+ logger.log(i18n(`${i18nKey}.success.updateExplanation`));
45
45
  } catch (e) {
46
46
  logger.error(
47
47
  i18n(`${i18nKey}.errors.update`, {
@@ -2,7 +2,7 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { uploadFolder, hasUploadErrors } = require('@hubspot/cli-lib');
4
4
  const { getFileMapperQueryValues } = require('@hubspot/cli-lib/fileMapper');
5
- const { upload } = require('@hubspot/cli-lib/api/fileMapper');
5
+ const { upload, deleteFile } = require('@hubspot/cli-lib/api/fileMapper');
6
6
  const {
7
7
  getCwd,
8
8
  convertToUnixPath,
@@ -26,6 +26,7 @@ const {
26
26
  getMode,
27
27
  } = require('../lib/commonOpts');
28
28
  const { uploadPrompt } = require('../lib/prompts/uploadPrompt');
29
+ const { cleanUploadPrompt } = require('../lib/prompts/cleanUploadPrompt');
29
30
  const { validateMode, loadAndValidateOptions } = require('../lib/validation');
30
31
  const { trackCommandUsage } = require('../lib/usageTracking');
31
32
  const { getUploadableFileList } = require('../lib/upload');
@@ -204,6 +205,29 @@ exports.handler = async options => {
204
205
  absoluteSrcPath,
205
206
  options.convertFields
206
207
  );
208
+
209
+ if (options.clean) {
210
+ // If clean is true, will first delete the dest folder and then upload src. Cleans up files that only exist on HS.
211
+ let cleanUpload = options.force;
212
+ if (!options.force) {
213
+ cleanUpload = await cleanUploadPrompt(accountId, dest);
214
+ }
215
+ if (cleanUpload) {
216
+ try {
217
+ await deleteFile(accountId, dest);
218
+ logger.log(
219
+ i18n(`${i18nKey}.cleaning`, { accountId, filePath: dest })
220
+ );
221
+ } catch (error) {
222
+ logger.error(
223
+ i18n(`${i18nKey}.errors.deleteFailed`, {
224
+ accountId,
225
+ path: dest,
226
+ })
227
+ );
228
+ }
229
+ }
230
+ }
207
231
  uploadFolder(
208
232
  accountId,
209
233
  absoluteSrcPath,
@@ -276,5 +300,15 @@ exports.builder = yargs => {
276
300
  type: 'boolean',
277
301
  default: false,
278
302
  });
303
+ yargs.option('clean', {
304
+ describe: i18n(`${i18nKey}.options.clean.describe`),
305
+ type: 'boolean',
306
+ default: false,
307
+ });
308
+ yargs.option('force', {
309
+ describe: i18n(`${i18nKey}.options.force.describe`),
310
+ type: 'boolean',
311
+ default: false,
312
+ });
279
313
  return yargs;
280
314
  };
package/lang/en.lyaml CHANGED
@@ -180,7 +180,7 @@ en:
180
180
  customObject:
181
181
  betaMessage: "The Custom Object CLI is currently in beta and is subject to change."
182
182
  describe: "Manage Custom Objects. This feature is currently in beta and the CLI contract is subject to change."
183
- seeMoreLink: "See {{ link }} to find out more."
183
+ seeMoreLink: "View our docs to find out more."
184
184
  subcommands:
185
185
  create:
186
186
  describe: "Create custom object instances"
@@ -456,10 +456,10 @@ en:
456
456
  describe: "Shortcut of the link you'd like to open"
457
457
  selectLink: "Select a link to open"
458
458
  project:
459
- describe: "{{#bold}}[beta]{{/bold}} Commands for working with projects. For more information, visit our documentation: https://developers.hubspot.com/docs/platform/build-and-deploy-using-hubspot-projects"
459
+ describe: "Commands for working with projects. For more information, visit our documentation: https://developers.hubspot.com/docs/platform/build-and-deploy-using-hubspot-projects"
460
460
  subcommands:
461
461
  dev:
462
- describe: "{{#bold}}[beta]{{/bold}} Start local dev for the current project"
462
+ describe: "Start local dev for the current project"
463
463
  logs:
464
464
  betaMessage: "HubSpot projects local development"
465
465
  nonSandboxWarning: "Testing in a sandbox is strongly recommended. To switch the target account, select an option below or run {{#bold}}`hs accounts use`{{/bold}} before running the command again."
@@ -480,7 +480,7 @@ en:
480
480
  examples:
481
481
  default: "Start local dev for the current project"
482
482
  create:
483
- describe: "{{#bold}}[beta]{{/bold}} Create a new project"
483
+ describe: "Create a new project"
484
484
  logs:
485
485
  welcomeMessage: "Welcome to HubSpot Developer Projects!"
486
486
  examples:
@@ -495,7 +495,7 @@ en:
495
495
  templateSource:
496
496
  describe: "Path to custom GitHub repository from which to create project template"
497
497
  add:
498
- describe: "{{#bold}}[beta]{{/bold}} Create a new component within a project"
498
+ describe: "Create a new component within a project"
499
499
  options:
500
500
  name:
501
501
  describe: "Component name"
@@ -510,13 +510,14 @@ en:
510
510
  examples:
511
511
  default: "Create a component within your project"
512
512
  deploy:
513
- describe: "{{#bold}}[beta]{{/bold}} Deploy a project build"
513
+ describe: "Deploy a project build"
514
514
  debug:
515
515
  deploying: "Deploying project at path: {{ path }}"
516
516
  errors:
517
517
  deploy: "Deploy error: {{ details }}"
518
518
  noBuilds: "Deploy error: no builds for this project were found."
519
519
  noBuildId: "You must specify a build to deploy"
520
+ projectNotFound: "{{ projectName }} does not exist in account {{ accountIdentifier }}. Run {{ command }} to upload your project files to HubSpot."
520
521
  examples:
521
522
  default: "Deploy the latest build of the current project"
522
523
  withOptions: "Deploy build 5 of the project my-project"
@@ -526,9 +527,9 @@ en:
526
527
  project:
527
528
  describe: "Project name"
528
529
  listBuilds:
529
- describe: "{{#bold}}[beta]{{/bold}} List the project's builds"
530
+ describe: "List the project's builds"
530
531
  logs:
531
- describe: "{{#bold}}[beta]{{/bold}} Get execution logs for a serverless function within a project"
532
+ describe: "Get execution logs for a serverless function within a project"
532
533
  errors:
533
534
  invalidAppName: "Could not find app with name \"{{ appName }}\" in project \"{{ projectName }}\""
534
535
  logs:
@@ -563,7 +564,7 @@ en:
563
564
  endpoint:
564
565
  describe: "Public endpoint path"
565
566
  upload:
566
- describe: "{{#bold}}[beta]{{/bold}} Upload your project files and create a new build"
567
+ describe: "Upload your project files and create a new build"
567
568
  examples:
568
569
  default: "Upload a project"
569
570
  logs:
@@ -581,7 +582,7 @@ en:
581
582
  path:
582
583
  describe: "Path to a project folder"
583
584
  watch:
584
- describe: "{{#bold}}[beta]{{/bold}} Watch your local project for changes and automatically upload changed files to a new build in HubSpot"
585
+ describe: "Watch your local project for changes and automatically upload changed files to a new build in HubSpot"
585
586
  examples:
586
587
  default: "Watch a project within the myProjectFolder folder"
587
588
  logs:
@@ -593,7 +594,7 @@ en:
593
594
  initialUpload:
594
595
  describe: "Upload directory before watching for updates"
595
596
  download:
596
- describe: "{{#bold}}[beta]{{/bold}} Download your project files from HubSpot and write to a path on your computer"
597
+ describe: "Download your project files from HubSpot and write to a path on your computer"
597
598
  examples:
598
599
  default: "Download the project myProject into myProjectFolder folder"
599
600
  logs:
@@ -612,7 +613,7 @@ en:
612
613
  dest:
613
614
  describe: "Destination folder for the project"
614
615
  open:
615
- describe: "{{#bold}}[beta]{{/bold}} Open the specified project's details page in the browser"
616
+ describe: "Open the specified project's details page in the browser"
616
617
  options:
617
618
  project:
618
619
  describe: "Name of project to open"
@@ -743,7 +744,7 @@ en:
743
744
  describe: "Name of the secret to be updated"
744
745
  success:
745
746
  update: "The secret \"{{ secretName }}\" was updated in the HubSpot account: {{ accountIdentifier }}"
746
- updateReupload: "Make sure to `{{#yellow}}upload{{/yellow}}` all serverless functions using this secret to access its new value."
747
+ updateExplanation: "Existing serverless functions will start using this new value within 10 seconds."
747
748
  theme:
748
749
  describe: "Commands for working with themes, including marketplace validation with the marketplace-validate subcommand."
749
750
  subcommands:
@@ -803,6 +804,7 @@ en:
803
804
  invalidPath: "The path \"{{ path }}\" is not a path to a file or folder"
804
805
  uploadFailed: "Uploading file \"{{ src }}\" to \"{{ dest }}\" failed"
805
806
  someFilesFailed: "One or more files failed to upload to \"{{ dest }}\" in the Design Manager"
807
+ deleteFailed: "Deleting \"{{ path }}\" from account {{ accountId }} failed"
806
808
  options:
807
809
  options:
808
810
  describe: "Options to pass to javascript fields files"
@@ -810,6 +812,10 @@ en:
810
812
  describe: "If true, saves all output from javascript fields files as 'fields.output.json'."
811
813
  convertFields:
812
814
  describe: "If true, converts any javascript fields files contained in module folder or project root."
815
+ clean:
816
+ describe: "Will cause upload to delete files in your HubSpot account that are not found locally."
817
+ force:
818
+ describe: "Skips confirmation prompts when doing a clean upload."
813
819
  previewUrl: "To preview this theme, visit: {{ previewUrl }}"
814
820
  positionals:
815
821
  src:
@@ -821,6 +827,7 @@ en:
821
827
  uploadComplete: "Uploading files to \"{{ dest }}\" in the Design Manager is complete"
822
828
  uploading: "Uploading files from \"{{ src }}\" to \"{{ dest }}\" in the Design Manager of account {{ accountId }}"
823
829
  notUploaded: "There was an error processing \"{{ src }}\". The file has not been uploaded."
830
+ cleaning: "Removing \"{{ filePath }}\" from account {{ accountId }} and uploading local..."
824
831
  watch:
825
832
  describe: "Watch a directory on your computer for changes and upload the changed files to the HubSpot CMS."
826
833
  errors:
@@ -865,8 +872,8 @@ en:
865
872
  noCompatibleComponents: "Skipping call to {{ serverKey }} because there are no compatible components in the project."
866
873
  LocalDevManager:
867
874
  failedToInitialize: "Missing required arguments to initialize Local Dev"
875
+ noDeployedBuild: "There is no deployed build for this project in {{ accountIdentifier }}. Run {{ uploadCommand }} to upload and deploy your project."
868
876
  noComponents: "There are no components in this project."
869
- noDeployedBuild: "There is no deployed build for this project in {{ accountIdentifier }}."
870
877
  noRunnableComponents: "There are no components in this project that support local development."
871
878
  betaMessage: "HubSpot projects local development"
872
879
  running: "Running {{#bold}}{{ projectName }}{{/bold}} locally on {{ accountIdentifier }}, waiting for changes ..."
@@ -878,13 +885,13 @@ en:
878
885
  uploadWarning:
879
886
  appLabel: "[App]"
880
887
  uiExtensionLabel: "[UI Extension]"
881
- configEdit: "You edited the configuration file {{#bold}}{{ path }}{{/bold}}. Changes to configuration files cannot be handled by the local dev server."
882
888
  missingComponents: "The deployed build for this project does not contain {{#bold}}'{{ missingComponents }}'{{/bold}}. This may cause issues in local development."
883
- header: "{{ reason }} To reflect these changes:"
889
+ defaultWarning: "Changing project configuration requires a new project build."
890
+ header: "{{ warning }} To reflect these changes and continue testing:"
884
891
  stopDev: " * Stop {{ command }}"
885
892
  runUpload: " * Run {{ command }}"
886
- runUploadWithAccount: " * Run {{ command }}"
887
893
  restartDev: " * Re-run {{ command }}"
894
+ pushToGithub: " * Commit and push your changes to GitHub"
888
895
  devServer:
889
896
  cleanupError: "Failed to cleanup local dev server: {{ message }}"
890
897
  setupError: "Failed to setup local dev server: {{ message }}"
@@ -960,7 +967,7 @@ en:
960
967
  message: "Run {{ command }} to upload your project to HubSpot and trigger builds"
961
968
  projectDevCommand:
962
969
  command: "hs project dev"
963
- message: "Run {{ command }} to start testing your project locally"
970
+ message: "Run {{ command }} to set up your test environment and start local development"
964
971
  sandboxSyncDevelopmentCommand:
965
972
  command: "hs sandbox sync"
966
973
  message: "Run {{ command }} to to update CRM object definitions in your sandbox"
@@ -989,7 +996,8 @@ en:
989
996
  createNewSandboxOption: "<Test on a new development sandbox>"
990
997
  chooseDefaultAccountOption: "<{{#bold}}\U00002757{{/bold}} Test on this production account {{#bold}}\U00002757{{/bold}}>"
991
998
  promptMessage: "[--account] Choose a sandbox under {{ accountIdentifier }} to test with:"
992
- sandboxLimit: "You’ve reached the limit of {{ limit }} development sandboxes"
999
+ sandboxLimit: "Your account reached the limit of {{ limit }} development sandboxes"
1000
+ sandboxLimitWithSuggestion: "Your account reached the limit of {{ limit }} development sandboxes. Run {{ authCommand }} to add an existing one to the config."
993
1001
  confirmDefaultSandboxAccount: "Continue testing on {{#bold}}{{ accountName }} ({{ accountType }}){{/bold}}? (Y/n)"
994
1002
  projectLogsPrompt:
995
1003
  projectName:
@@ -1109,7 +1117,7 @@ en:
1109
1117
  enterName: "[--project] Enter project name:"
1110
1118
  errors:
1111
1119
  invalidName: "You entered an invalid name. Please try again."
1112
- projectDoesNotExist: "Project \"{{ projectName }}\" could not be found in \"{{ accountId }}\""
1120
+ projectDoesNotExist: "Project {{#bold}}{{ projectName }}{{/bold}} could not be found in \"{{ accountIdentifier }}\""
1113
1121
  feedbackPrompt:
1114
1122
  feedbackType:
1115
1123
  message: "What type of feedback would you like to leave?"
@@ -1122,6 +1130,8 @@ en:
1122
1130
  errors:
1123
1131
  buildIdDoesNotExist: "Build {{ buildId }} does not exist for project {{ projectName }}."
1124
1132
  buildAlreadyDeployed: "Build {{ buildId }} is already deployed."
1133
+ cleanUploadPrompt:
1134
+ message: "You are about to remove any remote files in \"{{ filePath }}\" on HubSpot account {{ accountId }} that don't exist locally. Are you sure you want to do this?"
1125
1135
  convertFields:
1126
1136
  positionals:
1127
1137
  src:
@@ -23,7 +23,7 @@ const {
23
23
  UI_COLORS,
24
24
  uiCommandReference,
25
25
  uiAccountDescription,
26
- uiBetaMessage,
26
+ uiBetaTag,
27
27
  uiLink,
28
28
  uiLine,
29
29
  } = require('./ui');
@@ -44,6 +44,7 @@ class LocalDevManager {
44
44
  this.projectDir = options.projectDir;
45
45
  this.debug = options.debug || false;
46
46
  this.deployedBuild = options.deployedBuild;
47
+ this.isGithubLinked = options.isGithubLinked;
47
48
  this.watcher = null;
48
49
  this.uploadWarnings = {};
49
50
 
@@ -64,12 +65,13 @@ class LocalDevManager {
64
65
 
65
66
  // Local dev currently relies on the existence of a deployed build in the target account
66
67
  if (!this.deployedBuild) {
67
- logger.log();
68
68
  logger.error(
69
69
  i18n(`${i18nKey}.noDeployedBuild`, {
70
70
  accountIdentifier: uiAccountDescription(this.targetAccountId),
71
+ uploadCommand: this.getUploadCommand(),
71
72
  })
72
73
  );
74
+ logger.log();
73
75
  process.exit(EXIT_CODES.SUCCESS);
74
76
  }
75
77
 
@@ -77,7 +79,6 @@ class LocalDevManager {
77
79
 
78
80
  // The project is empty, there is nothing to run locally
79
81
  if (!components.length) {
80
- logger.log();
81
82
  logger.error(i18n(`${i18nKey}.noComponents`));
82
83
  process.exit(EXIT_CODES.SUCCESS);
83
84
  }
@@ -88,19 +89,19 @@ class LocalDevManager {
88
89
 
89
90
  // The project does not contain any components that support local development
90
91
  if (!runnableComponents.length) {
91
- logger.log();
92
92
  logger.error(i18n(`${i18nKey}.noRunnableComponents`));
93
93
  process.exit(EXIT_CODES.SUCCESS);
94
94
  }
95
95
 
96
- logger.log();
97
96
  const setupSucceeded = await this.devServerSetup(runnableComponents);
98
97
 
99
- if (setupSucceeded || !this.debug) {
98
+ if (!setupSucceeded) {
99
+ process.exit(EXIT_CODES.ERROR);
100
+ } else if (!this.debug) {
100
101
  console.clear();
101
102
  }
102
103
 
103
- uiBetaMessage(i18n(`${i18nKey}.betaMessage`));
104
+ uiBetaTag(i18n(`${i18nKey}.betaMessage`));
104
105
  logger.log();
105
106
  logger.log(
106
107
  chalk.hex(UI_COLORS.SORBET)(
@@ -165,32 +166,35 @@ class LocalDevManager {
165
166
  });
166
167
  }
167
168
 
169
+ getUploadCommand() {
170
+ const currentDefaultAccount = getConfigDefaultAccount();
171
+
172
+ return this.targetAccountId !== getAccountId(currentDefaultAccount)
173
+ ? uiCommandReference(
174
+ `hs project upload --account=${this.targetAccountId}`
175
+ )
176
+ : uiCommandReference('hs project upload');
177
+ }
178
+
168
179
  logUploadWarning(reason) {
180
+ const warning = reason || i18n(`${i18nKey}.uploadWarning.defaultWarning`);
181
+
169
182
  // Avoid logging the warning to the console if it is currently the most
170
183
  // recently logged warning. We do not want to spam the console with the same message.
171
- if (!this.uploadWarnings[reason]) {
172
- const currentDefaultAccount = getConfigDefaultAccount();
173
- const defaultAccountId = getAccountId(currentDefaultAccount);
174
-
184
+ if (!this.uploadWarnings[warning]) {
175
185
  logger.log();
176
- logger.warn(i18n(`${i18nKey}.uploadWarning.header`, { reason }));
186
+ logger.warn(i18n(`${i18nKey}.uploadWarning.header`, { warning }));
177
187
  logger.log(
178
188
  i18n(`${i18nKey}.uploadWarning.stopDev`, {
179
189
  command: uiCommandReference('hs project dev'),
180
190
  })
181
191
  );
182
- if (this.targetAccountId !== defaultAccountId) {
183
- logger.log(
184
- i18n(`${i18nKey}.uploadWarning.runUploadWithAccount`, {
185
- command: uiCommandReference(
186
- `hs project upload --account=${this.targetAccountId}`
187
- ),
188
- })
189
- );
192
+ if (this.isGithubLinked) {
193
+ logger.log(i18n(`${i18nKey}.uploadWarning.pushToGithub`));
190
194
  } else {
191
195
  logger.log(
192
196
  i18n(`${i18nKey}.uploadWarning.runUpload`, {
193
- command: uiCommandReference('hs project upload'),
197
+ command: this.getUploadCommand(),
194
198
  })
195
199
  );
196
200
  }
@@ -200,8 +204,8 @@ class LocalDevManager {
200
204
  })
201
205
  );
202
206
 
203
- this.mostRecentUploadWarning = reason;
204
- this.uploadWarnings[reason] = true;
207
+ this.mostRecentUploadWarning = warning;
208
+ this.uploadWarnings[warning] = true;
205
209
  }
206
210
  }
207
211
 
@@ -245,7 +249,7 @@ class LocalDevManager {
245
249
  !deployedComponentNames.includes(cardConfig.data.title)
246
250
  ) {
247
251
  missingComponents.push(
248
- `${i18n(`${i18nKey}.uploadWarning.appLabel`)} ${
252
+ `${i18n(`${i18nKey}.uploadWarning.uiExtensionLabel`)} ${
249
253
  cardConfig.data.title
250
254
  }`
251
255
  );
@@ -298,11 +302,7 @@ class LocalDevManager {
298
302
 
299
303
  handleWatchEvent(filePath, event, configPaths) {
300
304
  if (configPaths.includes(filePath)) {
301
- this.logUploadWarning(
302
- i18n(`${i18nKey}.uploadWarning.configEdit`, {
303
- path: path.relative(this.projectDir, filePath),
304
- })
305
- );
305
+ this.logUploadWarning();
306
306
  } else {
307
307
  this.devServerFileChange(filePath, event);
308
308
  }
package/lib/projects.js CHANGED
@@ -133,24 +133,15 @@ const createProjectConfig = async (
133
133
  }`
134
134
  );
135
135
 
136
+ await downloadGitHubRepoContents(templateSource, template.path, projectPath);
137
+ const _config = JSON.parse(fs.readFileSync(projectConfigPath));
138
+ writeProjectConfig(projectConfigPath, {
139
+ ..._config,
140
+ name: projectName,
141
+ });
142
+
136
143
  if (template.name === 'no-template') {
137
144
  fs.ensureDirSync(path.join(projectPath, 'src'));
138
-
139
- writeProjectConfig(projectConfigPath, {
140
- name: projectName,
141
- srcDir: 'src',
142
- });
143
- } else {
144
- await downloadGitHubRepoContents(
145
- templateSource,
146
- template.path,
147
- projectPath
148
- );
149
- const _config = JSON.parse(fs.readFileSync(projectConfigPath));
150
- writeProjectConfig(projectConfigPath, {
151
- ..._config,
152
- name: projectName,
153
- });
154
145
  }
155
146
 
156
147
  return true;
@@ -0,0 +1,20 @@
1
+ const { promptUser } = require('./promptUtils');
2
+ const { i18n } = require('../lang');
3
+
4
+ const i18nKey = 'cli.lib.prompts.cleanUploadPrompt';
5
+
6
+ const cleanUploadPrompt = async (accountId, filePath) => {
7
+ const promptAnswer = await promptUser([
8
+ {
9
+ name: 'cleanUpload',
10
+ message: i18n(`${i18nKey}.message`, { accountId, filePath }),
11
+ type: 'confirm',
12
+ default: false,
13
+ },
14
+ ]);
15
+ return promptAnswer.cleanUpload;
16
+ };
17
+
18
+ module.exports = {
19
+ cleanUploadPrompt,
20
+ };
@@ -1,6 +1,6 @@
1
1
  const { promptUser } = require('./promptUtils');
2
2
  const { i18n } = require('../lang');
3
- const { uiAccountDescription } = require('../ui');
3
+ const { uiAccountDescription, uiCommandReference } = require('../ui');
4
4
  const { isSandbox, getAccountName } = require('../sandboxes');
5
5
  const { getAccountId } = require('@hubspot/cli-lib');
6
6
  const { getSandboxUsageLimits } = require('@hubspot/cli-lib/sandboxes');
@@ -26,13 +26,24 @@ const selectTargetAccountPrompt = async (accounts, defaultAccountConfig) => {
26
26
  logger.debug('Unable to fetch sandbox usage limits: ', err);
27
27
  }
28
28
 
29
- const sandboxAccounts = accounts.reverse().filter(isSandbox);
29
+ const sandboxAccounts = accounts
30
+ .reverse()
31
+ .filter(
32
+ config => isSandbox(config) && config.parentAccountId === defaultAccountId
33
+ );
30
34
  let disabledMessage = false;
31
35
 
32
36
  if (sandboxUsage['DEVELOPER'] && sandboxUsage['DEVELOPER'].available === 0) {
33
- disabledMessage = i18n(`${i18nKey}.sandboxLimit`, {
34
- limit: sandboxUsage['DEVELOPER'].limit,
35
- });
37
+ if (sandboxAccounts.length < sandboxUsage['DEVELOPER'].limit) {
38
+ disabledMessage = i18n(`${i18nKey}.sandboxLimitWithSuggestion`, {
39
+ authCommand: uiCommandReference('hs auth'),
40
+ limit: sandboxUsage['DEVELOPER'].limit,
41
+ });
42
+ } else {
43
+ disabledMessage = i18n(`${i18nKey}.sandboxLimit`, {
44
+ limit: sandboxUsage['DEVELOPER'].limit,
45
+ });
46
+ }
36
47
  }
37
48
 
38
49
  // Order choices by Developer Sandbox -> Standard Sandbox
@@ -1,6 +1,7 @@
1
1
  const { promptUser } = require('./promptUtils');
2
2
  const { i18n } = require('../lang');
3
3
  const { ensureProjectExists } = require('../projects');
4
+ const { uiAccountDescription } = require('../ui');
4
5
 
5
6
  const i18nKey = 'cli.lib.prompts.projectNamePrompt';
6
7
 
@@ -20,7 +21,7 @@ const projectNamePrompt = (accountId, options = {}) => {
20
21
  if (!projectExists) {
21
22
  return i18n(`${i18nKey}.errors.projectDoesNotExist`, {
22
23
  projectName: val,
23
- accountId,
24
+ accountIdentifier: uiAccountDescription(accountId),
24
25
  });
25
26
  }
26
27
  return true;
package/lib/ui.js CHANGED
@@ -1,4 +1,3 @@
1
- const process = require('process');
2
1
  const chalk = require('chalk');
3
2
  const supportsHyperlinks = require('../lib/supportHyperlinks');
4
3
  const supportsColor = require('../lib/supportsColor');
@@ -42,11 +41,13 @@ const getTerminalUISupport = () => {
42
41
  * @param {object} options
43
42
  * @returns {string}
44
43
  */
45
- const uiLink = (linkText, url, { inSpinnies = false } = {}) => {
44
+ const uiLink = (linkText, url) => {
46
45
  const terminalUISupport = getTerminalUISupport();
47
46
  const encodedUrl = encodeURI(url);
47
+
48
48
  if (terminalUISupport.hyperlinks) {
49
49
  const CLOSE_SEQUENCE = '\u001B]8;;\u0007';
50
+
50
51
  const result = [
51
52
  '\u001B]8;;',
52
53
  encodedUrl,
@@ -55,16 +56,7 @@ const uiLink = (linkText, url, { inSpinnies = false } = {}) => {
55
56
  CLOSE_SEQUENCE,
56
57
  ].join('');
57
58
 
58
- // Required b/c spinnies will automatically line-break long lines. "indent" is added to account for indented spinnies
59
- // See https://github.com/jbcarpanelli/spinnies/blob/d672dedcab8c8ce0f6de0bb26ca5582bf602afd7/utils.js#L68-L74
60
- const indent = 5;
61
- const columns =
62
- (process.stderr.columns || 95) - CLOSE_SEQUENCE.length - indent;
63
- const validLength = !inSpinnies || result.length < columns;
64
-
65
- if (validLength) {
66
- return terminalUISupport.color ? chalk.cyan(result) : result;
67
- }
59
+ return terminalUISupport.color ? chalk.cyan(result) : result;
68
60
  }
69
61
 
70
62
  return terminalUISupport.color
@@ -95,7 +87,15 @@ const uiInfoSection = (title, logContent) => {
95
87
  };
96
88
 
97
89
  const uiCommandReference = command => {
98
- return chalk.bold(chalk.hex(UI_COLORS.MARIGOLD_DARK)(`\`${command}\``));
90
+ const terminalUISupport = getTerminalUISupport();
91
+
92
+ const commandReference = `\`${command}\``;
93
+
94
+ return chalk.bold(
95
+ terminalUISupport.color
96
+ ? chalk.hex(UI_COLORS.MARIGOLD_DARK)(commandReference)
97
+ : commandReference
98
+ );
99
99
  };
100
100
 
101
101
  const uiFeatureHighlight = (commands, title) => {
@@ -105,7 +105,7 @@ const uiFeatureHighlight = (commands, title) => {
105
105
  commands.forEach((c, i) => {
106
106
  const commandKey = `${i18nKey}.commandKeys.${c}`;
107
107
  const message = i18n(`${commandKey}.message`, {
108
- command: chalk.bold(i18n(`${commandKey}.command`)),
108
+ command: uiCommandReference(i18n(`${commandKey}.command`)),
109
109
  });
110
110
  if (i !== 0) {
111
111
  logger.log('');
@@ -115,26 +115,28 @@ const uiFeatureHighlight = (commands, title) => {
115
115
  });
116
116
  };
117
117
 
118
- const uiBetaMessage = message => {
118
+ const uiBetaTag = (message, log = true) => {
119
119
  const i18nKey = 'cli.lib.ui';
120
120
 
121
- logger.log(chalk.hex(UI_COLORS.SORBET)(i18n(`${i18nKey}.betaTag`)), message);
122
- };
121
+ const terminalUISupport = getTerminalUISupport();
122
+ const tag = i18n(`${i18nKey}.betaTag`);
123
123
 
124
- const uiBetaWarning = logMessage => {
125
- const i18nKey = 'cli.lib.ui.betaWarning';
124
+ const result = `${
125
+ terminalUISupport.color ? chalk.hex(UI_COLORS.SORBET)(tag) : tag
126
+ } ${message}`;
126
127
 
127
- logger.log(i18n(`${i18nKey}.header`));
128
- logMessage();
129
- logger.log(i18n(`${i18nKey}.footer`));
128
+ if (log) {
129
+ logger.log(result);
130
+ } else {
131
+ return result;
132
+ }
130
133
  };
131
134
 
132
135
  module.exports = {
133
136
  UI_COLORS,
134
137
  uiAccountDescription,
135
138
  uiCommandReference,
136
- uiBetaMessage,
137
- uiBetaWarning,
139
+ uiBetaTag,
138
140
  uiFeatureHighlight,
139
141
  uiInfoSection,
140
142
  uiLine,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "4.2.1-beta.3",
3
+ "version": "5.0.0",
4
4
  "description": "CLI for working with HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -10,7 +10,7 @@
10
10
  "dependencies": {
11
11
  "@hubspot/cli-lib": "^4.2.2",
12
12
  "@hubspot/serverless-dev-runtime": "4.2.1-beta.3",
13
- "@hubspot/ui-extensions-dev-server": "^0.7.0",
13
+ "@hubspot/ui-extensions-dev-server": "^0.7.2",
14
14
  "archiver": "^5.3.0",
15
15
  "chalk": "^4.1.2",
16
16
  "chokidar": "^3.0.1",
@@ -42,5 +42,5 @@
42
42
  "publishConfig": {
43
43
  "access": "public"
44
44
  },
45
- "gitHead": "e3e46fab20a9efb8c4c98f88b2aed1d13e6d0b1d"
45
+ "gitHead": "c84420be1abb52575cf159de243d41542653d0bb"
46
46
  }