@hubspot/cli 8.6.0 → 8.7.0-beta.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.
Files changed (149) hide show
  1. package/api/releases.d.ts +36 -0
  2. package/api/releases.js +41 -0
  3. package/bin/cli.js +3 -3
  4. package/commands/account/auth.js +2 -2
  5. package/commands/account/clean.js +2 -2
  6. package/commands/account/createOverride.js +2 -2
  7. package/commands/account/info.js +2 -2
  8. package/commands/account/link.js +2 -2
  9. package/commands/account/list.js +2 -2
  10. package/commands/account/remove.js +2 -2
  11. package/commands/account/removeOverride.js +2 -2
  12. package/commands/account/rename.js +2 -2
  13. package/commands/account/unlink.js +2 -2
  14. package/commands/account/use.js +2 -2
  15. package/commands/api.js +2 -2
  16. package/commands/app/migrate.js +2 -2
  17. package/commands/app/secret/add.js +2 -2
  18. package/commands/app/secret/delete.js +2 -2
  19. package/commands/app/secret/list.js +2 -2
  20. package/commands/app/secret/update.js +2 -2
  21. package/commands/auth.js +2 -2
  22. package/commands/cms/app/create.js +2 -2
  23. package/commands/cms/convertFields.js +2 -2
  24. package/commands/cms/delete.js +2 -2
  25. package/commands/cms/fetch.js +2 -2
  26. package/commands/cms/function/create.js +2 -2
  27. package/commands/cms/function/deploy.js +2 -2
  28. package/commands/cms/function/list.js +2 -2
  29. package/commands/cms/function/logs.js +2 -2
  30. package/commands/cms/function/server.js +2 -2
  31. package/commands/cms/getReactModule.js +2 -2
  32. package/commands/cms/lighthouseScore.js +2 -2
  33. package/commands/cms/lint.js +2 -2
  34. package/commands/cms/list.js +2 -2
  35. package/commands/cms/module/create.js +8 -2
  36. package/commands/cms/module/marketplace-validate.js +2 -2
  37. package/commands/cms/mv.js +2 -2
  38. package/commands/cms/template/create.js +2 -2
  39. package/commands/cms/theme/create.js +2 -2
  40. package/commands/cms/theme/generate-selectors.js +2 -2
  41. package/commands/cms/theme/marketplace-validate.js +2 -2
  42. package/commands/cms/theme/preview.js +2 -2
  43. package/commands/cms/upload.js +2 -2
  44. package/commands/cms/watch.js +2 -2
  45. package/commands/cms/webpack/create.js +2 -2
  46. package/commands/completion.js +2 -2
  47. package/commands/config/migrate.js +2 -2
  48. package/commands/config/set.js +2 -2
  49. package/commands/customObject/create.js +2 -2
  50. package/commands/customObject/createSchema.js +2 -2
  51. package/commands/customObject/deleteSchema.js +2 -2
  52. package/commands/customObject/fetchAllSchemas.js +2 -2
  53. package/commands/customObject/fetchSchema.js +2 -2
  54. package/commands/customObject/listSchemas.js +2 -2
  55. package/commands/customObject/updateSchema.js +2 -2
  56. package/commands/doctor.js +2 -2
  57. package/commands/feedback.js +2 -2
  58. package/commands/filemanager/fetch.js +2 -2
  59. package/commands/filemanager/upload.js +2 -2
  60. package/commands/getStarted.js +2 -2
  61. package/commands/hubdb/clear.js +2 -2
  62. package/commands/hubdb/create.js +2 -2
  63. package/commands/hubdb/delete.js +2 -2
  64. package/commands/hubdb/fetch.js +2 -2
  65. package/commands/hubdb/list.js +2 -2
  66. package/commands/init.js +2 -2
  67. package/commands/mcp/setup.js +2 -2
  68. package/commands/mcp/start.js +2 -2
  69. package/commands/open.js +2 -2
  70. package/commands/project/add.js +2 -2
  71. package/commands/project/appInstallStatus.d.ts +2 -2
  72. package/commands/project/appInstallStatus.js +3 -2
  73. package/commands/project/create.js +2 -2
  74. package/commands/project/delete.js +2 -2
  75. package/commands/project/deploy.js +2 -2
  76. package/commands/project/dev/index.js +2 -2
  77. package/commands/project/download.js +2 -2
  78. package/commands/project/info.d.ts +2 -2
  79. package/commands/project/info.js +3 -2
  80. package/commands/project/installDeps.js +2 -2
  81. package/commands/project/lint.js +7 -5
  82. package/commands/project/list.d.ts +2 -2
  83. package/commands/project/list.js +3 -2
  84. package/commands/project/listBuilds.js +2 -2
  85. package/commands/project/logs.js +2 -2
  86. package/commands/project/migrate.js +2 -2
  87. package/commands/project/open.js +2 -2
  88. package/commands/project/profile/add.js +2 -2
  89. package/commands/project/profile/delete.js +2 -2
  90. package/commands/project/release/create.d.ts +7 -0
  91. package/commands/project/release/create.js +159 -0
  92. package/commands/project/release/info.d.ts +6 -0
  93. package/commands/project/release/info.js +147 -0
  94. package/commands/project/release/list.d.ts +6 -0
  95. package/commands/project/release/list.js +111 -0
  96. package/commands/project/release.d.ts +3 -0
  97. package/commands/project/release.js +20 -0
  98. package/commands/project/updateDeps.js +2 -2
  99. package/commands/project/upload.d.ts +3 -0
  100. package/commands/project/upload.js +77 -9
  101. package/commands/project/validate.js +2 -2
  102. package/commands/project/watch.js +2 -2
  103. package/commands/project.js +2 -0
  104. package/commands/sandbox/create.js +2 -2
  105. package/commands/sandbox/delete.js +2 -2
  106. package/commands/secret/addSecret.js +2 -2
  107. package/commands/secret/deleteSecret.js +2 -2
  108. package/commands/secret/listSecret.js +2 -2
  109. package/commands/secret/updateSecret.js +2 -2
  110. package/commands/testAccount/create.js +2 -2
  111. package/commands/testAccount/createConfig.js +2 -2
  112. package/commands/testAccount/delete.js +2 -2
  113. package/commands/testAccount/importData.js +2 -2
  114. package/commands/upgrade.js +2 -2
  115. package/lang/en.d.ts +92 -0
  116. package/lang/en.js +92 -0
  117. package/lib/api/usageTracking.d.ts +29 -0
  118. package/lib/api/usageTracking.js +28 -0
  119. package/lib/commonOpts.js +0 -1
  120. package/lib/constants.d.ts +1 -0
  121. package/lib/constants.js +1 -0
  122. package/lib/projects/localDev/helpers/project.js +1 -1
  123. package/lib/projects/npmAuditOnUpload.d.ts +10 -0
  124. package/lib/projects/npmAuditOnUpload.js +73 -0
  125. package/lib/projects/pollProjectBuildAndDeploy.d.ts +5 -1
  126. package/lib/projects/pollProjectBuildAndDeploy.js +3 -2
  127. package/lib/projects/preview.d.ts +7 -0
  128. package/lib/projects/preview.js +48 -0
  129. package/lib/projects/uieLinting.d.ts +4 -0
  130. package/lib/projects/uieLinting.js +36 -1
  131. package/lib/projects/upload.d.ts +3 -1
  132. package/lib/projects/upload.js +26 -6
  133. package/lib/projects/validateLintConfigOnUpload.d.ts +9 -0
  134. package/lib/projects/validateLintConfigOnUpload.js +45 -0
  135. package/lib/projects/workspaces.d.ts +11 -1
  136. package/lib/projects/workspaces.js +27 -12
  137. package/lib/usageTracking.d.ts +7 -17
  138. package/lib/usageTracking.js +43 -29
  139. package/lib/yargs/makeWrappedYargsHandler.d.ts +3 -0
  140. package/lib/yargs/{makeYargsHandlerWithUsageTracking.js → makeWrappedYargsHandler.js} +29 -3
  141. package/mcp-server/tools/cms/HsCreateFunctionTool.js +2 -2
  142. package/mcp-server/tools/cms/HsCreateModuleTool.js +4 -5
  143. package/mcp-server/tools/cms/HsCreateTemplateTool.js +2 -2
  144. package/mcp-server/tools/cms/HsFunctionLogsTool.js +2 -3
  145. package/mcp-server/tools/cms/HsListFunctionsTool.js +2 -3
  146. package/mcp-server/tools/cms/HsListTool.js +2 -2
  147. package/mcp-server/utils/toolUsageTracking.js +10 -6
  148. package/package.json +4 -4
  149. package/lib/yargs/makeYargsHandlerWithUsageTracking.d.ts +0 -3
@@ -12,7 +12,7 @@ import { handleProjectUpload } from '../../lib/projects/upload.js';
12
12
  import { pollBuildStatus, pollDeployStatus, } from '../../lib/projects/pollProjectBuildAndDeploy.js';
13
13
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
14
14
  import { handleKeypress, handleExit } from '../../lib/process.js';
15
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
15
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
16
16
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
17
17
  import { uiDeprecatedTag } from '../../lib/ui/index.js';
18
18
  const command = 'watch';
@@ -146,7 +146,7 @@ const builder = makeYargsBuilder(projectWatchBuilder, command, describe, {
146
146
  const projectWatchCommand = {
147
147
  command,
148
148
  describe,
149
- handler: makeYargsHandlerWithUsageTracking('project-watch', handler),
149
+ handler: makeWrappedYargsHandler('project-watch', handler),
150
150
  builder,
151
151
  };
152
152
  export default projectWatchCommand;
@@ -15,6 +15,7 @@ import installDeps from './project/installDeps.js';
15
15
  import lint from './project/lint.js';
16
16
  import updateDeps from './project/updateDeps.js';
17
17
  import profile from './project/profile.js';
18
+ import release from './project/release.js';
18
19
  import projectValidate from './project/validate.js';
19
20
  import list from './project/list.js';
20
21
  import info from './project/info.js';
@@ -66,6 +67,7 @@ function projectBuilder(yargs) {
66
67
  .command(lint)
67
68
  .command(updateDeps)
68
69
  .command(profile)
70
+ .command(release)
69
71
  .command(projectValidate)
70
72
  .command(appInstallStatus)
71
73
  .demandCommand(1, '');
@@ -12,7 +12,7 @@ import { promptUser } from '../../lib/prompts/promptUtils.js';
12
12
  import { logError } from '../../lib/errorHandlers/index.js';
13
13
  import { buildV2Sandbox } from '../../lib/buildAccount.js';
14
14
  import { hubspotAccountNamePrompt } from '../../lib/prompts/accountNamePrompt.js';
15
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
15
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
16
16
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
17
17
  const command = 'create';
18
18
  const describe = uiBetaTag(commands.sandbox.subcommands.create.describe, false);
@@ -150,7 +150,7 @@ const builder = makeYargsBuilder(sandboxCreateBuilder, command, describe, {
150
150
  const sandboxCreateCommand = {
151
151
  command,
152
152
  describe,
153
- handler: makeYargsHandlerWithUsageTracking('sandbox-create', handler),
153
+ handler: makeWrappedYargsHandler('sandbox-create', handler),
154
154
  builder,
155
155
  };
156
156
  export default sandboxCreateCommand;
@@ -11,7 +11,7 @@ import { selectAccountFromConfig } from '../../lib/prompts/accountsPrompt.js';
11
11
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
12
12
  import { promptUser } from '../../lib/prompts/promptUtils.js';
13
13
  import { uiAuthCommandReference, uiBetaTag } from '../../lib/ui/index.js';
14
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
14
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
15
15
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
16
16
  const command = 'delete';
17
17
  const describe = uiBetaTag(commands.sandbox.subcommands.delete.describe, false);
@@ -182,7 +182,7 @@ const builder = makeYargsBuilder(sandboxDeleteBuilder, command, describe, {
182
182
  const sandboxDeleteCommand = {
183
183
  command,
184
184
  describe,
185
- handler: makeYargsHandlerWithUsageTracking('sandbox-delete', handler),
185
+ handler: makeWrappedYargsHandler('sandbox-delete', handler),
186
186
  builder,
187
187
  };
188
188
  export default sandboxDeleteCommand;
@@ -4,7 +4,7 @@ import { secretValuePrompt, secretNamePrompt, } from '../../lib/prompts/secretPr
4
4
  import { commands } from '../../lang/en.js';
5
5
  import { uiLogger } from '../../lib/ui/logger.js';
6
6
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
7
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
7
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
8
8
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
9
9
  const command = 'add [name]';
10
10
  const describe = commands.secret.subcommands.add.describe;
@@ -51,7 +51,7 @@ const builder = makeYargsBuilder(addSecretBuilder, command, describe, {
51
51
  const addSecretCommand = {
52
52
  command,
53
53
  describe,
54
- handler: makeYargsHandlerWithUsageTracking('secrets-add', handler),
54
+ handler: makeWrappedYargsHandler('secrets-add', handler),
55
55
  builder,
56
56
  };
57
57
  export default addSecretCommand;
@@ -5,7 +5,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
5
5
  import { ApiErrorContext, logError } from '../../lib/errorHandlers/index.js';
6
6
  import { commands } from './../../lang/en.js';
7
7
  import { uiLogger } from '../../lib/ui/logger.js';
8
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
8
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
9
9
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
10
10
  const command = 'delete [name]';
11
11
  const describe = commands.secret.subcommands.delete.describe;
@@ -64,7 +64,7 @@ const builder = makeYargsBuilder(deleteSecretBuilder, command, describe, {
64
64
  const deleteSecretCommand = {
65
65
  command,
66
66
  describe,
67
- handler: makeYargsHandlerWithUsageTracking('secrets-delete', handler),
67
+ handler: makeWrappedYargsHandler('secrets-delete', handler),
68
68
  builder,
69
69
  };
70
70
  export default deleteSecretCommand;
@@ -3,7 +3,7 @@ import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
3
3
  import { uiAccountDescription } from '../../lib/ui/index.js';
4
4
  import { commands } from '../../lang/en.js';
5
5
  import { uiLogger } from '../../lib/ui/logger.js';
6
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
6
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
7
7
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
8
8
  const command = 'list';
9
9
  const describe = commands.secret.subcommands.list.describe;
@@ -36,7 +36,7 @@ const builder = makeYargsBuilder(listSecretBuilder, command, describe, {
36
36
  const listSecretCommand = {
37
37
  command,
38
38
  describe,
39
- handler: makeYargsHandlerWithUsageTracking('secrets-list', handler),
39
+ handler: makeWrappedYargsHandler('secrets-list', handler),
40
40
  builder,
41
41
  };
42
42
  export default listSecretCommand;
@@ -4,7 +4,7 @@ import { ApiErrorContext, logError } from '../../lib/errorHandlers/index.js';
4
4
  import { secretValuePrompt, secretListPrompt, } from '../../lib/prompts/secretPrompt.js';
5
5
  import { commands } from '../../lang/en.js';
6
6
  import { uiLogger } from '../../lib/ui/logger.js';
7
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
7
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
8
8
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
9
9
  const command = 'update [name]';
10
10
  const describe = commands.secret.subcommands.update.describe;
@@ -50,7 +50,7 @@ const builder = makeYargsBuilder(updateSecretBuilder, command, describe, {
50
50
  const updateSecretCommand = {
51
51
  command,
52
52
  describe,
53
- handler: makeYargsHandlerWithUsageTracking('secrets-update', handler),
53
+ handler: makeWrappedYargsHandler('secrets-update', handler),
54
54
  builder,
55
55
  };
56
56
  export default updateSecretCommand;
@@ -3,7 +3,7 @@ import path from 'path';
3
3
  import { getValidEnv } from '@hubspot/local-dev-lib/environment';
4
4
  import { getConfigAccountEnvironment } from '@hubspot/local-dev-lib/config';
5
5
  import { getCwd } from '@hubspot/local-dev-lib/path';
6
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
6
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
7
7
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
8
8
  import { promptUser, listPrompt } from '../../lib/prompts/promptUtils.js';
9
9
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
@@ -230,7 +230,7 @@ const builder = makeYargsBuilder(createTestAccountBuilder, command, describe, {
230
230
  const createTestAccountCommand = {
231
231
  command,
232
232
  describe,
233
- handler: makeYargsHandlerWithUsageTracking('test-account-create', handler),
233
+ handler: makeWrappedYargsHandler('test-account-create', handler),
234
234
  builder,
235
235
  };
236
236
  export default createTestAccountCommand;
@@ -1,7 +1,7 @@
1
1
  import fs from 'fs-extra';
2
2
  import path from 'path';
3
3
  import { getCwd } from '@hubspot/local-dev-lib/path';
4
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
4
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
5
5
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
6
6
  import { promptUser } from '../../lib/prompts/promptUtils.js';
7
7
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
@@ -85,7 +85,7 @@ const builder = makeYargsBuilder(createTestAccountConfigBuilder, command, descri
85
85
  const createTestAccountConfigCommand = {
86
86
  command,
87
87
  describe,
88
- handler: makeYargsHandlerWithUsageTracking('test-account-create-config', handler),
88
+ handler: makeWrappedYargsHandler('test-account-create-config', handler),
89
89
  builder,
90
90
  };
91
91
  export default createTestAccountConfigCommand;
@@ -1,5 +1,5 @@
1
1
  import { fetchDeveloperTestAccounts, deleteDeveloperTestAccount, } from '@hubspot/local-dev-lib/api/developerTestAccounts';
2
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
2
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
3
3
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
4
4
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
5
5
  import { uiLogger } from '../../lib/ui/logger.js';
@@ -191,7 +191,7 @@ const builder = makeYargsBuilder(deleteTestAccountBuilder, command, describe, {
191
191
  const deleteTestAccountCommand = {
192
192
  command,
193
193
  describe,
194
- handler: makeYargsHandlerWithUsageTracking('test-account-delete', handler),
194
+ handler: makeWrappedYargsHandler('test-account-delete', handler),
195
195
  builder,
196
196
  };
197
197
  export default deleteTestAccountCommand;
@@ -1,6 +1,6 @@
1
1
  import { getImportDataRequest } from '@hubspot/local-dev-lib/crm';
2
2
  import { logError } from '../../lib/errorHandlers/index.js';
3
- import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
3
+ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
4
4
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
5
5
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
6
6
  import { importDataFilePathPrompt } from '../../lib/prompts/importDataFilePathPrompt.js';
@@ -55,6 +55,6 @@ const crmImportDataCommand = {
55
55
  command,
56
56
  describe,
57
57
  builder,
58
- handler: makeYargsHandlerWithUsageTracking('crm-import-data', handler),
58
+ handler: makeWrappedYargsHandler('crm-import-data', handler),
59
59
  };
60
60
  export default crmImportDataCommand;
@@ -1,7 +1,7 @@
1
1
  import { isConfigFlagEnabled } from '@hubspot/local-dev-lib/config';
2
2
  import { CONFIG_FLAGS } from '@hubspot/local-dev-lib/constants/config';
3
3
  import { EXIT_CODES } from '../lib/enums/exitCodes.js';
4
- import { makeYargsHandlerWithUsageTracking } from '../lib/yargs/makeYargsHandlerWithUsageTracking.js';
4
+ import { makeWrappedYargsHandler } from '../lib/yargs/makeWrappedYargsHandler.js';
5
5
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
6
6
  import { uiLogger } from '../lib/ui/logger.js';
7
7
  import { commands } from '../lang/en.js';
@@ -112,7 +112,7 @@ const builder = makeYargsBuilder(upgradeBuilder, command, describe, {
112
112
  const upgradeCommand = {
113
113
  command,
114
114
  describe,
115
- handler: makeYargsHandlerWithUsageTracking('upgrade', handler),
115
+ handler: makeWrappedYargsHandler('upgrade', handler),
116
116
  builder,
117
117
  };
118
118
  export default upgradeCommand;
package/lang/en.d.ts CHANGED
@@ -1729,6 +1729,67 @@ export declare const commands: {
1729
1729
  deployLatestBuild: string;
1730
1730
  };
1731
1731
  };
1732
+ release: {
1733
+ describe: string;
1734
+ create: {
1735
+ describe: string;
1736
+ verboseDescribe: string;
1737
+ confirmPrompt: (projectName: string, buildId: number) => string;
1738
+ success: (releaseTag: string, buildId: number) => string;
1739
+ cancelled: string;
1740
+ errors: {
1741
+ projectNotFound: (accountId: number, projectName: string) => string;
1742
+ noDeployedBuild: string;
1743
+ buildNotFound: (buildId: number, projectName: string) => string;
1744
+ buildNotDeployed: (buildId: number) => string;
1745
+ };
1746
+ options: {
1747
+ build: string;
1748
+ force: string;
1749
+ };
1750
+ examples: {
1751
+ default: string;
1752
+ withBuild: string;
1753
+ };
1754
+ };
1755
+ list: {
1756
+ describe: string;
1757
+ verboseDescribe: string;
1758
+ noReleases: string;
1759
+ showingReleases: (count: number, projectName: string) => string;
1760
+ continueOrExitPrompt: string;
1761
+ errors: {
1762
+ projectNotFound: (accountId: number, projectName: string) => string;
1763
+ };
1764
+ options: {
1765
+ limit: string;
1766
+ };
1767
+ examples: {
1768
+ default: string;
1769
+ withLimit: string;
1770
+ };
1771
+ };
1772
+ info: {
1773
+ describe: string;
1774
+ verboseDescribe: string;
1775
+ releaseDetails: (releaseTag: string, projectName: string) => string;
1776
+ components: string;
1777
+ noComponents: string;
1778
+ moreReleasesHint: string;
1779
+ selectRelease: (projectName: string) => string;
1780
+ errors: {
1781
+ releaseNotFound: (releaseTag: string, projectName: string) => string;
1782
+ noReleases: string;
1783
+ };
1784
+ options: {
1785
+ tag: string;
1786
+ };
1787
+ examples: {
1788
+ default: string;
1789
+ json: string;
1790
+ };
1791
+ };
1792
+ };
1732
1793
  listBuilds: {
1733
1794
  describe: string;
1734
1795
  continueOrExitPrompt: string;
@@ -1805,6 +1866,7 @@ export declare const commands: {
1805
1866
  examples: {
1806
1867
  default: string;
1807
1868
  withProfile: string;
1869
+ withPreview: string;
1808
1870
  };
1809
1871
  logs: {
1810
1872
  buildSucceeded: (buildId: number) => string;
@@ -1815,6 +1877,8 @@ export declare const commands: {
1815
1877
  errors: {
1816
1878
  noProjectConfig: string;
1817
1879
  projectLockedError: string;
1880
+ previewRequiresTarget: string;
1881
+ targetRequiresPreview: string;
1818
1882
  };
1819
1883
  options: {
1820
1884
  forceCreate: {
@@ -1826,6 +1890,15 @@ export declare const commands: {
1826
1890
  profile: {
1827
1891
  describe: string;
1828
1892
  };
1893
+ skipNpmAudit: {
1894
+ describe: string;
1895
+ };
1896
+ preview: {
1897
+ describe: string;
1898
+ };
1899
+ target: {
1900
+ describe: string;
1901
+ };
1829
1902
  };
1830
1903
  };
1831
1904
  watch: {
@@ -3089,6 +3162,9 @@ export declare const lib: {
3089
3162
  process: {
3090
3163
  exitDebug: (signal: string) => string;
3091
3164
  };
3165
+ handlerLogFile: {
3166
+ saved: (filePath: string) => string;
3167
+ };
3092
3168
  DevServerManager: {
3093
3169
  portConflict: (port: string) => string;
3094
3170
  notInitialized: string;
@@ -3391,8 +3467,24 @@ export declare const lib: {
3391
3467
  updatingPackageJsonWorkspaces: (packageJsonPath: string) => string;
3392
3468
  updatedWorkspaces: (workspaces: string) => string;
3393
3469
  updatedFileDependency: (packageName: string, relativePath: string) => string;
3470
+ lintPackagesNotConfigured: (packageRoot: string) => string;
3471
+ lintConfigNotFound: (packageRoot: string) => string;
3472
+ lintHubSpotRulesNotActive: (packageRoot: string) => string;
3473
+ npmAuditClean: (packageRoot: string) => string;
3474
+ npmAuditIssues: (packageRoot: string, details: string) => string;
3475
+ npmAuditNpmUnavailable: (packageRoot: string) => string;
3476
+ npmAuditNonZeroExit: (packageRoot: string, exitCode: number) => string;
3394
3477
  };
3395
3478
  };
3479
+ projectPreview: {
3480
+ triggeringPreview: (buildId: number, targetPortalId: number) => string;
3481
+ pollingStatus: (releaseTag: string, targetPortalId: number) => string;
3482
+ succeeded: (releaseTag: string, targetPortalId: number) => string;
3483
+ triggerFailed: string;
3484
+ pollFailed: string;
3485
+ warning: string;
3486
+ missingProjectId: string;
3487
+ };
3396
3488
  importData: {
3397
3489
  errors: {
3398
3490
  incorrectAccountType: (derivedAccountId: number) => string;
package/lang/en.js CHANGED
@@ -1746,6 +1746,67 @@ export const commands = {
1746
1746
  deployLatestBuild: 'Deploy the latest build of the current project',
1747
1747
  },
1748
1748
  },
1749
+ release: {
1750
+ describe: 'Manage project releases.',
1751
+ create: {
1752
+ describe: 'Create a release for a project build.',
1753
+ verboseDescribe: `Create a release for a project build\n\nReleases mark a deployed build with an auto-generated semantic version tag (e.g. v1.0.0). The build must have been successfully deployed before it can be released.\n\nBy default, the latest deployed build is used. Use ${uiCommandReference('--build')} to specify a different build ID.`,
1754
+ confirmPrompt: (projectName, buildId) => `Create a release for project ${chalk.bold(projectName)} using build ${chalk.bold(String(buildId))}?`,
1755
+ success: (releaseTag, buildId) => `Release ${chalk.bold(releaseTag)} created for build ${chalk.bold(String(buildId))}.`,
1756
+ cancelled: 'Release creation cancelled.',
1757
+ errors: {
1758
+ projectNotFound: (accountId, projectName) => `The project ${chalk.bold(projectName)} does not exist in account ${uiAccountDescription(accountId)}. Run ${uiCommandReference('hs project upload')} to upload your project files to HubSpot.`,
1759
+ noDeployedBuild: `No deployed build found for this project. Run ${uiCommandReference('hs project deploy')} first.`,
1760
+ buildNotFound: (buildId, projectName) => `Build ${chalk.bold(String(buildId))} was not found for project ${chalk.bold(projectName)}. Run ${uiCommandReference('hs project list-builds')} to view existing builds or ${uiCommandReference('hs project deploy')} to deploy a build first.`,
1761
+ buildNotDeployed: (buildId) => `Build ${chalk.bold(String(buildId))} has not been deployed. Run ${uiCommandReference('hs project deploy')} first.`,
1762
+ },
1763
+ options: {
1764
+ build: 'Build ID to release. Defaults to the latest deployed build.',
1765
+ force: 'Skip confirmation prompt.',
1766
+ },
1767
+ examples: {
1768
+ default: 'Create a release for the latest deployed build',
1769
+ withBuild: 'Create a release for a specific build',
1770
+ },
1771
+ },
1772
+ list: {
1773
+ describe: 'List releases for the current project.',
1774
+ verboseDescribe: `List releases for the current project\n\nDisplays all releases in sorted order, newest first. Includes the version tag, build ID, and creation date. Use ${uiCommandReference('--limit')} to control how many results are shown.`,
1775
+ noReleases: 'No releases found for this project.',
1776
+ showingReleases: (count, projectName) => `Showing ${count} release${count === 1 ? '' : 's'} for ${chalk.bold(projectName)}:`,
1777
+ continueOrExitPrompt: 'Press <enter> to load more, or ctrl+c to exit',
1778
+ errors: {
1779
+ projectNotFound: (accountId, projectName) => `The project ${chalk.bold(projectName)} does not exist in account ${uiAccountDescription(accountId)}. Run ${uiCommandReference('hs project upload')} to upload your project files to HubSpot.`,
1780
+ },
1781
+ options: {
1782
+ limit: 'Number of releases to show',
1783
+ },
1784
+ examples: {
1785
+ default: 'List releases for the current project',
1786
+ withLimit: 'Show only the 5 most recent releases',
1787
+ },
1788
+ },
1789
+ info: {
1790
+ describe: 'Show details about a specific release.',
1791
+ verboseDescribe: `Show details about a specific release\n\nDisplays the release tag, build ID, creation date, and list of components included in the release. Use ${uiCommandReference('--json')} for machine-readable output.`,
1792
+ releaseDetails: (releaseTag, projectName) => `Release ${chalk.bold(releaseTag)} for ${chalk.bold(projectName)}:`,
1793
+ components: 'Components:',
1794
+ noComponents: 'No components found for this release.',
1795
+ moreReleasesHint: `Not all releases are shown. Use ${uiCommandReference('--tag')} to look up an older release directly.`,
1796
+ selectRelease: (projectName) => `Select a release for ${chalk.bold(projectName)}`,
1797
+ errors: {
1798
+ releaseNotFound: (releaseTag, projectName) => `Release ${chalk.bold(releaseTag)} was not found for project ${chalk.bold(projectName)}. Verify the project has been uploaded and the release tag exists. Run ${uiCommandReference('hs project release list')} to view existing releases.`,
1799
+ noReleases: 'No releases found for this project.',
1800
+ },
1801
+ options: {
1802
+ tag: 'Release tag to look up (e.g. v1.0.0)',
1803
+ },
1804
+ examples: {
1805
+ default: 'Show details about a specific release',
1806
+ json: 'Output release details as JSON',
1807
+ },
1808
+ },
1809
+ },
1749
1810
  listBuilds: {
1750
1811
  describe: "List the project's builds.",
1751
1812
  continueOrExitPrompt: 'Press <enter> to load more, or ctrl+c to exit',
@@ -1822,6 +1883,7 @@ export const commands = {
1822
1883
  examples: {
1823
1884
  default: 'Upload a project into your HubSpot account',
1824
1885
  withProfile: 'Upload a project into your HubSpot account when using profiles',
1886
+ withPreview: 'Upload and preview the build on a target portal',
1825
1887
  },
1826
1888
  logs: {
1827
1889
  buildSucceeded: (buildId) => `Build #${buildId} succeeded\n`,
@@ -1832,6 +1894,8 @@ export const commands = {
1832
1894
  errors: {
1833
1895
  noProjectConfig: 'No project detected. Run this command from a project directory.',
1834
1896
  projectLockedError: `Your project is locked. This may mean that another user is running the ${uiCommandReference('hs project dev')} command for this project. If this is you, unlock the project in Projects UI.`,
1897
+ previewRequiresTarget: `${uiCommandReference('--preview')} requires ${uiCommandReference('--target=<portalId>')} to specify the portal to preview on.`,
1898
+ targetRequiresPreview: `${uiCommandReference('--target')} can only be used with ${uiCommandReference('--preview')}.`,
1835
1899
  },
1836
1900
  options: {
1837
1901
  forceCreate: {
@@ -1843,6 +1907,15 @@ export const commands = {
1843
1907
  profile: {
1844
1908
  describe: 'Profile to target for this upload',
1845
1909
  },
1910
+ skipNpmAudit: {
1911
+ describe: 'Skip the npm audit security check before uploading',
1912
+ },
1913
+ preview: {
1914
+ describe: 'Preview the build on a target portal after a successful upload',
1915
+ },
1916
+ target: {
1917
+ describe: 'Portal ID to preview the build on',
1918
+ },
1846
1919
  },
1847
1920
  },
1848
1921
  watch: {
@@ -3115,6 +3188,9 @@ export const lib = {
3115
3188
  process: {
3116
3189
  exitDebug: (signal) => `Attempting to gracefully exit. Triggered by ${signal}`,
3117
3190
  },
3191
+ handlerLogFile: {
3192
+ saved: (filePath) => `Debug logs can be viewed at ${filePath}`,
3193
+ },
3118
3194
  DevServerManager: {
3119
3195
  portConflict: (port) => `The port ${port} is already in use.`,
3120
3196
  notInitialized: 'The Dev Server Manager must be initialized before it is started.',
@@ -3417,8 +3493,24 @@ export const lib = {
3417
3493
  updatingPackageJsonWorkspaces: (packageJsonPath) => `Updating package.json workspaces in archive: ${packageJsonPath}`,
3418
3494
  updatedWorkspaces: (workspaces) => ` Updated workspaces: ${workspaces}`,
3419
3495
  updatedFileDependency: (packageName, relativePath) => ` Updated dependencies.${packageName}: file:${relativePath}`,
3496
+ lintPackagesNotConfigured: (packageRoot) => `Project lint: lint packages not installed for ${chalk.bold(packageRoot)}. Run ${uiCommandReference('hs project lint')} to install them.`,
3497
+ lintConfigNotFound: (packageRoot) => `Project lint: ESLint configuration not found for ${chalk.bold(packageRoot)}. Run ${uiCommandReference('hs project lint')} to create an ESLint config.`,
3498
+ lintHubSpotRulesNotActive: (packageRoot) => `Project lint: HubSpot ESLint rules not active for ${chalk.bold(packageRoot)}. Configure ${chalk.bold('@hubspot/eslint-config-ui-extensions')} — see ${uiLink('setup instructions', 'https://www.npmjs.com/package/@hubspot/eslint-config-ui-extensions')}.`,
3499
+ npmAuditClean: (packageRoot) => `npm audit: No npm dependency issues found for ${chalk.bold(packageRoot)}`,
3500
+ npmAuditIssues: (packageRoot, details) => `npm audit: security issues found for ${chalk.bold(packageRoot)}: ${details}`,
3501
+ npmAuditNpmUnavailable: (packageRoot) => `npm audit: skipped for ${chalk.bold(packageRoot)} (npm not available in PATH)`,
3502
+ npmAuditNonZeroExit: (packageRoot, exitCode) => `npm audit: ${chalk.bold(packageRoot)} exited with code ${exitCode}`,
3420
3503
  },
3421
3504
  },
3505
+ projectPreview: {
3506
+ triggeringPreview: (buildId, targetPortalId) => `Previewing build #${buildId} on ${uiAccountDescription(targetPortalId)}`,
3507
+ pollingStatus: (releaseTag, targetPortalId) => `Previewing ${chalk.bold(releaseTag)} on ${uiAccountDescription(targetPortalId)}`,
3508
+ succeeded: (releaseTag, targetPortalId) => `Previewed ${chalk.bold(releaseTag)} on ${uiAccountDescription(targetPortalId)}`,
3509
+ triggerFailed: 'Failed to trigger preview',
3510
+ pollFailed: 'Failed to poll preview status',
3511
+ warning: 'The build succeeded but the preview failed. You can manually preview this build from the project UI.',
3512
+ missingProjectId: 'Unable to preview: could not resolve the project ID.',
3513
+ },
3422
3514
  importData: {
3423
3515
  errors: {
3424
3516
  incorrectAccountType: (derivedAccountId) => `The account ${uiAccountDescription(derivedAccountId)} is not a standard account, developer test account, or app developer account.`,
@@ -0,0 +1,29 @@
1
+ export type ConfigType = 'local' | 'global';
2
+ export type ExecutionSource = 'ci' | 'mcp' | 'user';
3
+ export type UsageTrackingMeta = {
4
+ action?: string;
5
+ os?: string;
6
+ nodeVersion?: string;
7
+ nodeMajorVersion?: string;
8
+ version?: string;
9
+ command?: string;
10
+ authType?: string;
11
+ step?: string;
12
+ assetType?: string;
13
+ mode?: string;
14
+ type?: string | number;
15
+ file?: boolean;
16
+ successful?: boolean;
17
+ configType?: ConfigType;
18
+ executionSource?: ExecutionSource;
19
+ platformVersion?: string;
20
+ executionTime?: number;
21
+ };
22
+ export type UsageTrackingRequest = {
23
+ portalId?: number;
24
+ accountId?: number;
25
+ eventName: string;
26
+ eventClass: string;
27
+ meta: UsageTrackingMeta;
28
+ };
29
+ export declare function sendUsageEvent(request: UsageTrackingRequest): Promise<void>;
@@ -0,0 +1,28 @@
1
+ import { http } from '@hubspot/local-dev-lib/http';
2
+ import { http as unauthedHttp } from '@hubspot/local-dev-lib/http/unauthed';
3
+ import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
4
+ const USAGE_PATH = 'local/dev/tools/proxy/v1/usage';
5
+ const USAGE_AUTHENTICATED_PATH = `${USAGE_PATH}/authenticated`;
6
+ export async function sendUsageEvent(request) {
7
+ const { accountId } = request;
8
+ if (accountId) {
9
+ try {
10
+ const account = getConfigAccountById(accountId);
11
+ if (account?.authType === 'personalaccesskey') {
12
+ await http.post(accountId, {
13
+ url: USAGE_AUTHENTICATED_PATH,
14
+ data: request,
15
+ });
16
+ return;
17
+ }
18
+ }
19
+ catch (_e) { }
20
+ }
21
+ try {
22
+ await unauthedHttp.post({
23
+ url: USAGE_PATH,
24
+ data: request,
25
+ });
26
+ }
27
+ catch (_e) { }
28
+ }
package/lib/commonOpts.js CHANGED
@@ -76,7 +76,6 @@ export function addJSONOutputOptions(yargs) {
76
76
  alias: 'format-output-as-json',
77
77
  describe: lib.commonOpts.options.jsonOutput,
78
78
  type: 'boolean',
79
- hidden: true,
80
79
  });
81
80
  }
82
81
  // Remove this once we've upgraded to yargs 18.0.0
@@ -4,6 +4,7 @@ export declare const FEEDBACK_INTERVAL: 10;
4
4
  export declare const HUBSPOT_FOLDER: "@hubspot";
5
5
  export declare const MARKETPLACE_FOLDER: "@marketplace";
6
6
  export declare const DEFAULT_POLLING_DELAY = 2000;
7
+ export declare const PREVIEW_POLL_TIMEOUT: number;
7
8
  export declare const PROJECT_CONFIG_FILE: "hsproject.json";
8
9
  export declare const PROJECT_BUILD_STATES: {
9
10
  readonly BUILDING: "BUILDING";
package/lib/constants.js CHANGED
@@ -4,6 +4,7 @@ export const FEEDBACK_INTERVAL = 10;
4
4
  export const HUBSPOT_FOLDER = '@hubspot';
5
5
  export const MARKETPLACE_FOLDER = '@marketplace';
6
6
  export const DEFAULT_POLLING_DELAY = 2000;
7
+ export const PREVIEW_POLL_TIMEOUT = 5 * 60 * 1000;
7
8
  export const PROJECT_CONFIG_FILE = 'hsproject.json';
8
9
  export const PROJECT_BUILD_STATES = {
9
10
  BUILDING: 'BUILDING',
@@ -70,7 +70,7 @@ function projectUploadCallback(accountId, projectConfig, tempFile, exit, buildId
70
70
  uiLogger.error(lib.localDevHelpers.project.createInitialBuildForNewProject.genericError);
71
71
  return exit(EXIT_CODES.ERROR);
72
72
  }
73
- return pollProjectBuildAndDeploy(accountId, projectConfig, tempFile, buildId, true);
73
+ return pollProjectBuildAndDeploy(accountId, projectConfig, tempFile, buildId, { silenceLogs: true });
74
74
  }
75
75
  // Create an initial build if the project was newly created in the account
76
76
  // Return the newly deployed build
@@ -0,0 +1,10 @@
1
+ import type { ParsedPackageJson } from '@hubspot/project-parsing-lib/workspaces';
2
+ export declare function summarizeNpmAuditJson(source: string): string | null;
3
+ type RunNpmAuditsBeforeProjectUploadArgs = {
4
+ srcDir: string;
5
+ projectDir: string;
6
+ parsedPackageJsons: ParsedPackageJson[];
7
+ isLegacyPlatform: boolean;
8
+ };
9
+ export declare function runNpmAuditsBeforeProjectUpload({ srcDir, projectDir, parsedPackageJsons, isLegacyPlatform, }: RunNpmAuditsBeforeProjectUploadArgs): Promise<void>;
10
+ export {};