@hubspot/cli 8.11.0-beta.0 → 8.12.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 (57) hide show
  1. package/commands/account/clean.js +1 -1
  2. package/commands/account/list.js +1 -1
  3. package/commands/account/remove.js +1 -1
  4. package/commands/account/rename.js +1 -1
  5. package/commands/account/use.js +1 -1
  6. package/commands/api.d.ts +4 -1
  7. package/commands/api.js +11 -14
  8. package/commands/project/appInstallStatus.d.ts +2 -1
  9. package/commands/project/appInstallStatus.js +19 -17
  10. package/commands/project/create.js +0 -1
  11. package/commands/project/deploy.d.ts +2 -1
  12. package/commands/project/deploy.js +31 -14
  13. package/commands/project/dev/index.js +18 -64
  14. package/commands/project/info.d.ts +2 -1
  15. package/commands/project/info.js +8 -6
  16. package/commands/project/installApp.d.ts +2 -1
  17. package/commands/project/installApp.js +25 -26
  18. package/commands/project/list.js +1 -1
  19. package/commands/project/release/create.d.ts +2 -1
  20. package/commands/project/release/create.js +68 -69
  21. package/commands/project/release/info.d.ts +2 -1
  22. package/commands/project/release/info.js +7 -6
  23. package/commands/project/release/list.d.ts +2 -1
  24. package/commands/project/release/list.js +14 -6
  25. package/commands/project/upload.d.ts +2 -1
  26. package/commands/project/upload.js +23 -20
  27. package/commands/project.js +2 -2
  28. package/commands/testAccount/create.d.ts +2 -1
  29. package/commands/testAccount/create.js +7 -7
  30. package/lang/en.d.ts +21 -28
  31. package/lang/en.js +30 -37
  32. package/lib/commonOpts.js +6 -1
  33. package/lib/constants.d.ts +1 -0
  34. package/lib/constants.js +1 -0
  35. package/lib/jsonOutput.d.ts +109 -0
  36. package/lib/jsonOutput.js +94 -0
  37. package/lib/projects/builds.d.ts +2 -0
  38. package/lib/projects/builds.js +22 -0
  39. package/lib/projects/localDev/DevSessionManager.d.ts +2 -2
  40. package/lib/projects/localDev/DevSessionManager.js +4 -30
  41. package/lib/projects/localDev/helpers/account.d.ts +0 -7
  42. package/lib/projects/localDev/helpers/account.js +1 -80
  43. package/lib/projects/release.d.ts +4 -0
  44. package/lib/projects/release.js +90 -0
  45. package/lib/yargs/makeWrappedYargsHandler.d.ts +5 -1
  46. package/lib/yargs/makeWrappedYargsHandler.js +123 -65
  47. package/mcp-server/Tool.js +32 -26
  48. package/mcp-server/utils/logger.d.ts +3 -0
  49. package/mcp-server/utils/logger.js +30 -0
  50. package/package.json +10 -8
  51. package/types/Yargs.d.ts +3 -1
  52. package/commands/project/dev/deprecatedFlow.d.ts +0 -11
  53. package/commands/project/dev/deprecatedFlow.js +0 -180
  54. package/lib/projects/localDev/DevServerManager_DEPRECATED.d.ts +0 -43
  55. package/lib/projects/localDev/DevServerManager_DEPRECATED.js +0 -128
  56. package/lib/projects/localDev/LocalDevManager_DEPRECATED.d.ts +0 -64
  57. package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +0 -394
@@ -1,6 +1,8 @@
1
- import { fetchProject, getBuildStatus, } from '@hubspot/local-dev-lib/api/projects';
2
- import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
1
+ import { handleProjectUpload } from '../../../lib/projects/upload.js';
2
+ import { pollProjectBuildAndDeploy } from '../../../lib/projects/pollProjectBuildAndDeploy.js';
3
+ import { resolveBuildId, validateBuildForRelease, executeRelease, } from '../../../lib/projects/release.js';
3
4
  import { logError, ApiErrorContext } from '../../../lib/errorHandlers/index.js';
5
+ import { isPromptExitError } from '../../../lib/errors/PromptExitError.js';
4
6
  import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/config.js';
5
7
  import { confirmPrompt } from '../../../lib/prompts/promptUtils.js';
6
8
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
@@ -8,64 +10,23 @@ import { uiLogger } from '../../../lib/ui/logger.js';
8
10
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
9
11
  import { commands } from '../../../lang/en.js';
10
12
  import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
11
- import { createRelease } from '../../../api/releases.js';
13
+ import { ReleaseSchema, mapReleaseToJsonOutput, } from '../../../lib/jsonOutput.js';
12
14
  const command = 'create';
13
15
  // const describe = commands.project.release.create.describe;
14
16
  const describe = undefined;
15
17
  // const verboseDescribe = commands.project.release.create.verboseDescribe;
16
18
  const verboseDescribe = undefined;
17
- async function resolveBuildId(accountId, projectName, buildOption) {
18
- const { data: { deployedBuildId }, } = await fetchProject(accountId, projectName);
19
- if (buildOption) {
20
- return buildOption;
21
- }
22
- if (!deployedBuildId) {
23
- throw new Error(commands.project.release.create.errors.noDeployedBuild);
24
- }
25
- return deployedBuildId;
26
- }
27
- async function validateBuild(accountId, projectName, buildId) {
28
- try {
29
- await getBuildStatus(accountId, projectName, buildId);
30
- }
31
- catch (e) {
32
- if (isHubSpotHttpError(e) && e.status === 404) {
33
- uiLogger.error(commands.project.release.create.errors.buildNotFound(buildId, projectName));
34
- }
35
- else {
36
- logError(e, new ApiErrorContext({
37
- accountId,
38
- request: 'project release create',
39
- }));
40
- }
41
- throw e;
42
- }
43
- }
44
- async function executeRelease(accountId, projectName, buildId, formatOutputAsJson) {
45
- try {
46
- const { data: release } = await createRelease(accountId, projectName, buildId);
47
- if (formatOutputAsJson) {
48
- uiLogger.json(release);
49
- }
50
- else {
51
- uiLogger.success(commands.project.release.create.success(release.releaseTag, release.buildId));
52
- }
53
- }
54
- catch (e) {
55
- if (isHubSpotHttpError(e) && e.status === 422) {
56
- uiLogger.error(commands.project.release.create.errors.buildNotDeployed(buildId));
57
- }
58
- else {
59
- logError(e, new ApiErrorContext({
60
- accountId,
61
- request: 'project release create',
62
- }));
63
- }
64
- throw e;
19
+ function logUploadError(error, accountId) {
20
+ if (!error) {
21
+ return;
65
22
  }
23
+ logError(error, new ApiErrorContext({
24
+ accountId,
25
+ request: 'project release create',
26
+ }));
66
27
  }
67
28
  async function handler(args) {
68
- const { exit, derivedAccountId, build: buildOption, json: formatOutputAsJson, force, } = args;
29
+ const { exit, derivedAccountId, build: buildOption, json: formatOutputAsJson, force, addJsonOutput, } = args;
69
30
  const { projectConfig, projectDir } = await getProjectConfig();
70
31
  try {
71
32
  validateProjectConfig(projectConfig, projectDir);
@@ -74,34 +35,66 @@ async function handler(args) {
74
35
  logError(error);
75
36
  return exit(EXIT_CODES.ERROR);
76
37
  }
38
+ if (!projectConfig || !projectDir) {
39
+ return exit(EXIT_CODES.ERROR);
40
+ }
77
41
  const projectName = projectConfig.name;
78
42
  let buildId;
79
43
  try {
80
- buildId = await resolveBuildId(derivedAccountId, projectName, buildOption);
44
+ buildId = await resolveBuildId(derivedAccountId, projectName, buildOption, force);
81
45
  }
82
46
  catch (e) {
83
- if (isHubSpotHttpError(e) && e.status === 404) {
84
- uiLogger.error(commands.project.release.create.errors.projectNotFound(derivedAccountId, projectName));
85
- }
86
- else if (!(e instanceof Error) || !e.message) {
87
- logError(e, new ApiErrorContext({
88
- accountId: derivedAccountId,
89
- request: 'project release create',
90
- }));
91
- }
92
- else {
93
- uiLogger.error(e.message);
47
+ if (isPromptExitError(e)) {
48
+ return exit(e.exitCode);
94
49
  }
50
+ logError(e, new ApiErrorContext({
51
+ accountId: derivedAccountId,
52
+ request: 'project release create',
53
+ }));
54
+ return exit(EXIT_CODES.ERROR);
55
+ }
56
+ if (buildId === null) {
95
57
  return exit(EXIT_CODES.ERROR);
96
58
  }
97
- if (buildOption) {
59
+ if (!buildId && !force) {
60
+ let shouldUpload;
98
61
  try {
99
- await validateBuild(derivedAccountId, projectName, buildId);
62
+ shouldUpload = await confirmPrompt(commands.project.release.create.uploadPrompt(projectName));
63
+ }
64
+ catch (e) {
65
+ if (isPromptExitError(e)) {
66
+ return exit(e.exitCode);
67
+ }
68
+ throw e;
69
+ }
70
+ if (!shouldUpload) {
71
+ return exit(EXIT_CODES.SUCCESS);
72
+ }
73
+ }
74
+ if (!buildId) {
75
+ const { result: pollResult, uploadError, projectNotFound, } = await handleProjectUpload({
76
+ accountId: derivedAccountId,
77
+ projectConfig,
78
+ projectDir,
79
+ sendIR: true,
80
+ callbackFunc: (...args) => pollProjectBuildAndDeploy(...args, { skipDeploy: true }),
81
+ });
82
+ if (projectNotFound || !pollResult || !pollResult.succeeded) {
83
+ logUploadError(uploadError, derivedAccountId);
84
+ return exit(EXIT_CODES.ERROR);
100
85
  }
101
- catch {
86
+ buildId = pollResult.buildId;
87
+ }
88
+ try {
89
+ const supportsReleases = await validateBuildForRelease(derivedAccountId, projectName, buildId);
90
+ if (!supportsReleases) {
91
+ uiLogger.error(commands.project.release.create.errors.incompatibleBuildVersion);
102
92
  return exit(EXIT_CODES.ERROR);
103
93
  }
104
94
  }
95
+ catch {
96
+ return exit(EXIT_CODES.ERROR);
97
+ }
105
98
  if (!formatOutputAsJson && !force) {
106
99
  const confirmed = await confirmPrompt(commands.project.release.create.confirmPrompt(projectName, buildId));
107
100
  if (!confirmed) {
@@ -110,7 +103,11 @@ async function handler(args) {
110
103
  }
111
104
  }
112
105
  try {
113
- await executeRelease(derivedAccountId, projectName, buildId, !!formatOutputAsJson);
106
+ const release = await executeRelease(derivedAccountId, projectName, buildId);
107
+ addJsonOutput(mapReleaseToJsonOutput(release));
108
+ if (!formatOutputAsJson) {
109
+ uiLogger.success(commands.project.release.create.success(release.releaseTag, release.buildId));
110
+ }
114
111
  }
115
112
  catch {
116
113
  return exit(EXIT_CODES.ERROR);
@@ -154,6 +151,8 @@ const projectReleaseCreateCommand = {
154
151
  command,
155
152
  describe,
156
153
  builder,
157
- handler: makeWrappedYargsHandler('project-release-create', handler),
154
+ handler: makeWrappedYargsHandler('project-release-create', handler, {
155
+ jsonOutputSchema: ReleaseSchema,
156
+ }),
158
157
  };
159
158
  export default projectReleaseCreateCommand;
@@ -1,5 +1,6 @@
1
1
  import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../../types/Yargs.js';
2
- export type ProjectReleaseInfoArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs & {
2
+ import { ReleaseJsonOutput } from '../../../lib/jsonOutput.js';
3
+ export type ProjectReleaseInfoArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ReleaseJsonOutput> & {
3
4
  tag?: string;
4
5
  };
5
6
  declare const projectReleaseInfoCommand: YargsCommandModule<unknown, ProjectReleaseInfoArgs>;
@@ -12,6 +12,7 @@ import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHand
12
12
  import { isPromptExitError } from '../../../lib/errors/PromptExitError.js';
13
13
  import { mapToUserFacingType } from '@hubspot/project-parsing-lib/transform';
14
14
  import { AUTO_GENERATED_COMPONENT_TYPES } from '@hubspot/project-parsing-lib/constants';
15
+ import { ReleaseSchema, mapReleaseToJsonOutput, } from '../../../lib/jsonOutput.js';
15
16
  const command = 'info';
16
17
  // const describe = commands.project.release.info.describe;
17
18
  const describe = undefined;
@@ -36,7 +37,7 @@ async function selectReleasePrompt(accountId, projectName) {
36
37
  });
37
38
  }
38
39
  async function handler(args) {
39
- const { derivedAccountId, tag: rawTag, json: formatOutputAsJson, exit, } = args;
40
+ const { derivedAccountId, tag: rawTag, json: formatOutputAsJson, exit, addJsonOutput, } = args;
40
41
  const { projectConfig, projectDir } = await getProjectConfig();
41
42
  try {
42
43
  validateProjectConfig(projectConfig, projectDir);
@@ -69,10 +70,8 @@ async function handler(args) {
69
70
  }
70
71
  try {
71
72
  const { data: release } = await getReleaseInfo(derivedAccountId, projectName, tag);
72
- if (formatOutputAsJson) {
73
- uiLogger.json(release);
74
- }
75
- else {
73
+ addJsonOutput(mapReleaseToJsonOutput(release));
74
+ if (!formatOutputAsJson) {
76
75
  uiLogger.log(commands.project.release.info.releaseDetails(release.releaseTag, projectName));
77
76
  renderTable(['Release', 'Build', 'Created'], [
78
77
  [
@@ -142,6 +141,8 @@ const projectReleaseInfoCommand = {
142
141
  command,
143
142
  describe,
144
143
  builder,
145
- handler: makeWrappedYargsHandler('project-release-info', handler),
144
+ handler: makeWrappedYargsHandler('project-release-info', handler, {
145
+ jsonOutputSchema: ReleaseSchema,
146
+ }),
146
147
  };
147
148
  export default projectReleaseInfoCommand;
@@ -1,5 +1,6 @@
1
1
  import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../../types/Yargs.js';
2
- export type ProjectReleaseListArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs & {
2
+ import { ReleaseListJsonOutput } from '../../../lib/jsonOutput.js';
3
+ export type ProjectReleaseListArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ReleaseListJsonOutput> & {
3
4
  limit?: number;
4
5
  };
5
6
  declare const projectReleaseListCommand: YargsCommandModule<unknown, ProjectReleaseListArgs>;
@@ -10,6 +10,7 @@ import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
10
10
  import { commands } from '../../../lang/en.js';
11
11
  import { renderTable } from '../../../ui/render.js';
12
12
  import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
13
+ import { ReleaseListSchema, mapReleaseToJsonOutput, } from '../../../lib/jsonOutput.js';
13
14
  const command = 'list';
14
15
  // const describe = commands.project.release.list.describe;
15
16
  const describe = undefined;
@@ -41,14 +42,14 @@ async function fetchAndDisplayReleases(accountId, projectName, options) {
41
42
  }
42
43
  }
43
44
  async function handler(args) {
44
- const { derivedAccountId, limit, json: formatOutputAsJson } = args;
45
+ const { derivedAccountId, limit, json: formatOutputAsJson, exit, addJsonOutput, } = args;
45
46
  const { projectConfig, projectDir } = await getProjectConfig();
46
47
  try {
47
48
  validateProjectConfig(projectConfig, projectDir);
48
49
  }
49
50
  catch (error) {
50
51
  logError(error);
51
- process.exit(EXIT_CODES.ERROR);
52
+ return exit(EXIT_CODES.ERROR);
52
53
  }
53
54
  const projectName = projectConfig.name;
54
55
  try {
@@ -56,7 +57,12 @@ async function handler(args) {
56
57
  const { data } = await listReleases(derivedAccountId, projectName, {
57
58
  limit,
58
59
  });
59
- uiLogger.json(data);
60
+ addJsonOutput({
61
+ results: data.results.map(mapReleaseToJsonOutput),
62
+ paging: data.paging
63
+ ? { next: { after: data.paging.next.after } }
64
+ : undefined,
65
+ });
60
66
  }
61
67
  else {
62
68
  await fetchAndDisplayReleases(derivedAccountId, projectName, { limit });
@@ -75,9 +81,9 @@ async function handler(args) {
75
81
  request: 'project release list',
76
82
  }));
77
83
  }
78
- process.exit(EXIT_CODES.ERROR);
84
+ return exit(EXIT_CODES.ERROR);
79
85
  }
80
- process.exit(EXIT_CODES.SUCCESS);
86
+ return exit(EXIT_CODES.SUCCESS);
81
87
  }
82
88
  function projectReleaseListBuilder(yargs) {
83
89
  yargs.options({
@@ -106,6 +112,8 @@ const projectReleaseListCommand = {
106
112
  command,
107
113
  describe,
108
114
  builder,
109
- handler: makeWrappedYargsHandler('project-release-list', handler),
115
+ handler: makeWrappedYargsHandler('project-release-list', handler, {
116
+ jsonOutputSchema: ReleaseListSchema,
117
+ }),
110
118
  };
111
119
  export default projectReleaseListCommand;
@@ -1,5 +1,6 @@
1
1
  import { CommonArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
2
- export type ProjectUploadArgs = CommonArgs & JSONOutputArgs & {
2
+ import { UploadJsonOutput } from '../../lib/jsonOutput.js';
3
+ export type ProjectUploadArgs = CommonArgs & JSONOutputArgs<UploadJsonOutput> & {
3
4
  force: boolean;
4
5
  forceCreate: boolean;
5
6
  message: string;
@@ -2,7 +2,7 @@ import chalk from 'chalk';
2
2
  import { uiLogger } from '../../lib/ui/logger.js';
3
3
  import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
4
4
  import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
5
- import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
5
+ import { isLegacyProject, meetsMinimumPlatformVersion, } from '@hubspot/project-parsing-lib/projects';
6
6
  import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
7
7
  import { logFeedbackMessage } from '../../lib/projects/ui.js';
8
8
  import { handleProjectUpload } from '../../lib/projects/upload.js';
@@ -14,9 +14,11 @@ import { PROJECT_ERROR_TYPES } from '../../lib/constants.js';
14
14
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
15
15
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
16
16
  import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
17
+ import { UploadSchema, } from '../../lib/jsonOutput.js';
17
18
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
18
19
  import { projectProfilePrompt } from '../../lib/prompts/projectProfilePrompt.js';
19
20
  import { showMcpPromotionNudge } from '../../lib/mcp/promotion.js';
21
+ import { PLATFORM_VERSIONS } from '@hubspot/project-parsing-lib/constants';
20
22
  const command = 'upload';
21
23
  const describe = commands.project.upload.describe;
22
24
  async function handlePreview(accountId, projectId, buildId, targetPortalId) {
@@ -34,8 +36,7 @@ async function handlePreview(accountId, projectId, buildId, targetPortalId) {
34
36
  };
35
37
  }
36
38
  async function handler(args) {
37
- const { force = false, forceCreate = false, message, derivedAccountId, skipValidation, skipNpmAudit, skipAutoDeploy, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, preview, target: targetPortalId, exit, addUsageMetadata, } = args;
38
- const jsonOutput = {};
39
+ const { force = false, forceCreate = false, message, derivedAccountId, skipValidation, skipNpmAudit, skipAutoDeploy, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, preview, target: targetPortalId, exit, addUsageMetadata, addJsonOutput, } = args;
39
40
  const { projectConfig, projectDir } = await getProjectConfig();
40
41
  try {
41
42
  validateProjectConfig(projectConfig, projectDir);
@@ -113,30 +114,33 @@ async function handler(args) {
113
114
  (!result.buildResult.isAutoDeployEnabled || preview || skipAutoDeploy)) {
114
115
  uiLogger.log(chalk.bold(commands.project.upload.logs.buildSucceeded(result.buildId)));
115
116
  if (!preview) {
116
- const deployCommand = `hs project deploy --build=${result.buildId}`;
117
- uiLogger.log(skipAutoDeploy
118
- ? commands.project.upload.logs.autoDeploySkipped(deployCommand)
119
- : commands.project.upload.logs.autoDeployDisabled(deployCommand));
117
+ if (meetsMinimumPlatformVersion(result.buildResult.platformVersion, PLATFORM_VERSIONS.v2026_09_BETA)) {
118
+ const releaseCommand = `hs project release create --build=${result.buildId}`;
119
+ uiLogger.log(commands.project.upload.logs.releaseManagementRequired(releaseCommand));
120
+ }
121
+ else {
122
+ const deployCommand = `hs project deploy --build=${result.buildId}`;
123
+ uiLogger.log(skipAutoDeploy
124
+ ? commands.project.upload.logs.autoDeploySkipped(deployCommand)
125
+ : commands.project.upload.logs.autoDeployDisabled(deployCommand));
126
+ }
120
127
  logFeedbackMessage(result.buildId);
121
128
  }
122
129
  await displayWarnLogs(targetAccountId, projectConfig.name, result.buildId);
123
130
  }
124
131
  if (result && result.succeeded && preview && targetPortalId) {
125
132
  const previewJson = await handlePreview(targetAccountId, projectId, result.buildId, targetPortalId);
126
- if (previewJson && formatOutputAsJson) {
127
- jsonOutput.preview = previewJson;
133
+ if (previewJson) {
134
+ addJsonOutput({ preview: previewJson });
128
135
  }
129
136
  }
130
- if (result && result.succeeded && formatOutputAsJson) {
131
- jsonOutput.buildId = result.buildId;
137
+ if (result) {
138
+ addJsonOutput({ buildId: result.buildId });
132
139
  if (result.deployResult) {
133
- jsonOutput.deployId = result.deployResult.deployId;
140
+ addJsonOutput({ deployId: result.deployResult.deployId });
134
141
  }
135
142
  }
136
143
  if (result && !result.succeeded) {
137
- if (formatOutputAsJson) {
138
- uiLogger.json(jsonOutput);
139
- }
140
144
  return exit(EXIT_CODES.ERROR);
141
145
  }
142
146
  if (!result && !uploadError) {
@@ -150,10 +154,7 @@ async function handler(args) {
150
154
  }));
151
155
  return exit(EXIT_CODES.ERROR);
152
156
  }
153
- if (formatOutputAsJson) {
154
- uiLogger.json(jsonOutput);
155
- }
156
- else {
157
+ if (!formatOutputAsJson) {
157
158
  await showMcpPromotionNudge(args._.join(' '));
158
159
  }
159
160
  return exit(EXIT_CODES.SUCCESS);
@@ -245,7 +246,9 @@ const builder = makeYargsBuilder(projectUploadBuilder, command, describe, {
245
246
  const projectUploadCommand = {
246
247
  command,
247
248
  describe,
248
- handler: makeWrappedYargsHandler('project-upload', handler),
249
+ handler: makeWrappedYargsHandler('project-upload', handler, {
250
+ jsonOutputSchema: UploadSchema,
251
+ }),
249
252
  builder,
250
253
  };
251
254
  export default projectUploadCommand;
@@ -24,7 +24,7 @@ import appInstallStatus from './project/appInstallStatus.js';
24
24
  import installApp from './project/installApp.js';
25
25
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
26
26
  import { getProjectConfig } from '../lib/projects/config.js';
27
- import { isSupportedPlatformVersion, LATEST_SUPPORTED_PLATFORM_VERSION, } from '@hubspot/project-parsing-lib/projects';
27
+ import { isKnownPlatformVersion, LATEST_SUPPORTED_PLATFORM_VERSION, } from '@hubspot/project-parsing-lib/projects';
28
28
  import { uiLogger } from '../lib/ui/logger.js';
29
29
  import { debugError } from '../lib/errorHandlers/index.js';
30
30
  const command = ['project', 'projects'];
@@ -37,7 +37,7 @@ async function validatePlatformVersion() {
37
37
  // Only warn if a platform version is explicitly set but not supported
38
38
  // Don't warn if the platform version is missing/undefined
39
39
  if (projectConfig?.platformVersion &&
40
- !isSupportedPlatformVersion(projectConfig.platformVersion)) {
40
+ !isKnownPlatformVersion(projectConfig.platformVersion)) {
41
41
  uiLogger.warn(lib.projects.platformVersion.unsupported(pkg.version, LATEST_SUPPORTED_PLATFORM_VERSION, projectConfig.platformVersion));
42
42
  uiLogger.log('');
43
43
  }
@@ -1,6 +1,7 @@
1
1
  import { AccountLevel } from '@hubspot/local-dev-lib/types/developerTestAccounts.js';
2
2
  import { CommonArgs, ConfigArgs, AccountArgs, TestingArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
3
- type CreateTestAccountArgs = CommonArgs & AccountArgs & ConfigArgs & TestingArgs & EnvironmentArgs & JSONOutputArgs & {
3
+ import { CreateTestAccountJsonOutput } from '../../lib/jsonOutput.js';
4
+ type CreateTestAccountArgs = CommonArgs & AccountArgs & ConfigArgs & TestingArgs & EnvironmentArgs & JSONOutputArgs<CreateTestAccountJsonOutput> & {
4
5
  configPath?: string;
5
6
  name?: string;
6
7
  description?: string;
@@ -4,6 +4,7 @@ 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
6
  import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
7
+ import { CreateTestAccountSchema, } from '../../lib/jsonOutput.js';
7
8
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
8
9
  import { promptUser, listPrompt } from '../../lib/prompts/promptUtils.js';
9
10
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
@@ -88,7 +89,7 @@ async function buildTestAccountConfig(args) {
88
89
  });
89
90
  }
90
91
  async function handler(args) {
91
- const { derivedAccountId, formatOutputAsJson, exit } = args;
92
+ const { derivedAccountId, formatOutputAsJson, exit, addJsonOutput } = args;
92
93
  const env = getValidEnv(getConfigAccountEnvironment(derivedAccountId));
93
94
  let testAccountConfig;
94
95
  try {
@@ -121,11 +122,8 @@ async function handler(args) {
121
122
  SpinniesManager.succeed('createTestAccount', {
122
123
  text: commands.testAccount.create.polling.success(testAccountConfig.accountName, resultJson.accountId, derivedAccountId),
123
124
  });
124
- if (formatOutputAsJson) {
125
- uiLogger.json(resultJson);
126
- }
127
- else {
128
- // Only save to config if not using json output
125
+ addJsonOutput(resultJson);
126
+ if (!formatOutputAsJson) {
129
127
  try {
130
128
  const savedAccountName = await saveAccountToConfig(resultJson.accountId, testAccountConfig.accountName, env, resultJson.personalAccessKey);
131
129
  // Inform user if the account name was normalized
@@ -230,7 +228,9 @@ const builder = makeYargsBuilder(createTestAccountBuilder, command, describe, {
230
228
  const createTestAccountCommand = {
231
229
  command,
232
230
  describe,
233
- handler: makeWrappedYargsHandler('test-account-create', handler),
231
+ handler: makeWrappedYargsHandler('test-account-create', handler, {
232
+ jsonOutputSchema: CreateTestAccountSchema,
233
+ }),
234
234
  builder,
235
235
  };
236
236
  export default createTestAccountCommand;
package/lang/en.d.ts CHANGED
@@ -1503,26 +1503,19 @@ export declare const commands: {
1503
1503
  describe: string;
1504
1504
  logs: {
1505
1505
  header: string;
1506
- placeholderAccountSelection: string;
1507
- accountTypeInformation: string;
1508
1506
  learnMoreMessageV2: string;
1509
- learnMoreMessageLegacy: string;
1510
1507
  profileProjectAccountExplanation: (accountId: number, profileName: string) => string;
1511
1508
  defaultProjectAccountExplanation: (accountId: number) => string;
1512
1509
  projectAccountFlagExplanation: (accountId: number) => string;
1513
- accountFlagExplanation: (accountId: number) => string;
1514
1510
  defaultSandboxOrDevTestTestingAccountExplanation: (accountId: number) => string;
1515
1511
  testingAccountFlagExplanation: (accountId: number) => string;
1516
1512
  };
1517
1513
  errors: {
1518
1514
  noProjectConfig: string;
1519
1515
  noAccount: (accountId: number) => string;
1520
- noAccountsInConfig: string;
1521
- invalidProjectComponents: string;
1516
+ unsupportedPlatformVersion: (platformVersion: string) => string;
1522
1517
  noRunnableComponents: string;
1523
1518
  accountNotCombined: string;
1524
- unsupportedAccountFlagLegacy: string;
1525
- unsupportedAccountFlagV2: string;
1526
1519
  localDevAlreadyRunning: string;
1527
1520
  };
1528
1521
  examples: {
@@ -1535,7 +1528,6 @@ export declare const commands: {
1535
1528
  profile: string;
1536
1529
  projectAccount: string;
1537
1530
  testingAccount: string;
1538
- account: string;
1539
1531
  port: string;
1540
1532
  };
1541
1533
  };
@@ -1723,7 +1715,9 @@ export declare const commands: {
1723
1715
  errors: {
1724
1716
  deploy: string;
1725
1717
  noBuilds: string;
1718
+ noSuccessfulBuilds: string;
1726
1719
  noBuildId: string;
1720
+ notSupportedForBuildVersion: string;
1727
1721
  projectNotFound: (accountId: number, projectName: string) => string;
1728
1722
  buildIdDoesNotExist: (accountId: number, buildId: number, projectName: string) => string;
1729
1723
  buildAlreadyDeployed: (accountId: number, buildId: number, projectName: string) => string;
@@ -1754,11 +1748,20 @@ export declare const commands: {
1754
1748
  confirmPrompt: (projectName: string, buildId: number) => string;
1755
1749
  success: (releaseTag: string, buildId: number) => string;
1756
1750
  cancelled: string;
1751
+ buildIdPrompt: string;
1752
+ noUploadMessage: string;
1753
+ buildStatus: {
1754
+ BUILDING: string;
1755
+ FAILURE: string;
1756
+ PENDING: string;
1757
+ PREPARING: string;
1758
+ };
1759
+ uploadPrompt: (projectName: string) => string;
1757
1760
  errors: {
1758
1761
  projectNotFound: (accountId: number, projectName: string) => string;
1759
- noDeployedBuild: string;
1760
1762
  buildNotFound: (buildId: number, projectName: string) => string;
1761
- buildNotDeployed: (buildId: number) => string;
1763
+ noSuccessfulBuilds: (projectName: string) => string;
1764
+ incompatibleBuildVersion: string;
1762
1765
  };
1763
1766
  options: {
1764
1767
  build: string;
@@ -1891,6 +1894,7 @@ export declare const commands: {
1891
1894
  runCommand: (command: string) => string;
1892
1895
  autoDeployDisabled: (deployCommand: string) => string;
1893
1896
  autoDeploySkipped: (deployCommand: string) => string;
1897
+ releaseManagementRequired: (releaseCommand: string) => string;
1894
1898
  };
1895
1899
  errors: {
1896
1900
  noProjectConfig: string;
@@ -3341,6 +3345,10 @@ export declare const lib: {
3341
3345
  handlerLogFile: {
3342
3346
  saved: (filePath: string) => string;
3343
3347
  };
3348
+ jsonSchema: {
3349
+ noSchemaForCommand: string;
3350
+ validationFailed: string;
3351
+ };
3344
3352
  DevServerManager: {
3345
3353
  portConflict: (port: string) => string;
3346
3354
  notInitialized: string;
@@ -3486,19 +3494,6 @@ export declare const lib: {
3486
3494
  };
3487
3495
  };
3488
3496
  account: {
3489
- checkIfDefaultAccountIsSupported: {
3490
- publicApp: string;
3491
- privateApp: string;
3492
- };
3493
- validateAccountOption: {
3494
- invalidPublicAppAccount: string;
3495
- invalidPrivateAppAccount: string;
3496
- nonSandboxWarning: string;
3497
- publicAppNonDeveloperTestAccountWarning: string;
3498
- };
3499
- checkIfParentAccountIsAuthed: {
3500
- notAuthedError: (parentAccountId: number | string, accountIdentifier: string) => string;
3501
- };
3502
3497
  selectAccountTypePrompt: {
3503
3498
  message: string;
3504
3499
  developerTestAccountOption: string;
@@ -3506,10 +3501,7 @@ export declare const lib: {
3506
3501
  sandboxAccountOptionDisabled: string;
3507
3502
  productionAccountOption: (accountId?: number) => string;
3508
3503
  };
3509
- confirmDefaultAccountIsTarget: {
3510
- configError: string;
3511
- declineDefaultAccountExplanation: string;
3512
- };
3504
+ declineDefaultAccountExplanation: string;
3513
3505
  };
3514
3506
  };
3515
3507
  middleware: {
@@ -3832,6 +3824,7 @@ export declare const lib: {
3832
3824
  qa: string;
3833
3825
  useEnv: string;
3834
3826
  jsonOutput: string;
3827
+ jsonSchema: string;
3835
3828
  debug: string;
3836
3829
  };
3837
3830
  };