@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
package/lang/en.js CHANGED
@@ -1518,26 +1518,19 @@ export const commands = {
1518
1518
  describe: 'Start local dev for the current project.',
1519
1519
  logs: {
1520
1520
  header: 'HubSpot projects local development',
1521
- placeholderAccountSelection: 'Using default account as target account (for now)',
1522
- accountTypeInformation: 'Testing in a developer test account is strongly recommended, but you can use a sandbox account if your plan allows you to create one.',
1523
1521
  learnMoreMessageV2: `Learn more about ${uiLink('HubSpot projects local dev', 'https://developers.hubspot.com/docs/developer-tooling/local-development/hubspot-cli/project-commands#start-a-local-development-server')} | ${uiLink('HubSpot account types', 'https://developers.hubspot.com/docs/getting-started/account-types')}`,
1524
- learnMoreMessageLegacy: uiLink('Learn more about the projects local dev server', 'https://developers.hubspot.com/docs/developer-tooling/local-development/hubspot-cli/project-commands#start-a-local-development-server'),
1525
1522
  profileProjectAccountExplanation: (accountId, profileName) => `Using account ${uiAccountDescription(accountId)} from profile ${chalk.bold(profileName)} for project upload`,
1526
1523
  defaultProjectAccountExplanation: (accountId) => `Using default account ${uiAccountDescription(accountId)} for project upload`,
1527
1524
  projectAccountFlagExplanation: (accountId) => `Using account ${uiAccountDescription(accountId)} provided by the --project-account flag for project upload`,
1528
- accountFlagExplanation: (accountId) => `Using account ${uiAccountDescription(accountId)} provided by the --account flag for project upload`,
1529
1525
  defaultSandboxOrDevTestTestingAccountExplanation: (accountId) => `Using default account ${uiAccountDescription(accountId)} for testing`,
1530
1526
  testingAccountFlagExplanation: (accountId) => `Using account ${uiAccountDescription(accountId)} provided by the --testing-account flag for testing`,
1531
1527
  },
1532
1528
  errors: {
1533
1529
  noProjectConfig: 'No project detected. Please run this command again from a project directory.',
1534
1530
  noAccount: (accountId) => `An error occurred while reading account ${uiAccountDescription(accountId)} from your config. Run ${uiAuthCommandReference()} to re-auth this account.`,
1535
- noAccountsInConfig: `No accounts found in your config. Run ${uiAuthCommandReference()} to configure a HubSpot account with the CLI.`,
1536
- invalidProjectComponents: 'Projects cannot contain both private and public apps. Move your apps to separate projects before attempting local development.',
1531
+ unsupportedPlatformVersion: (platformVersion) => `Local development is not supported for platform version ${chalk.bold(platformVersion)}. Please upgrade to 2025.2 or later.`,
1537
1532
  noRunnableComponents: `No supported components were found in this project. Run ${uiCommandReference('hs project add')} to see a list of available components and add one to your project.`,
1538
1533
  accountNotCombined: `\nLocal development of unified apps is currently only compatible with accounts that are opted into the unified apps beta. Make sure that this account is opted in or switch accounts using ${uiCommandReference('hs account use')}.`,
1539
- unsupportedAccountFlagLegacy: 'The --project-account and --testing-account flags are not supported for projects with platform versions earlier than 2025.2.',
1540
- unsupportedAccountFlagV2: 'The --account flag is not supported for projects with platform versions 2025.2 and newer. Use --testing-account and --project-account flags to specify accounts to use for local dev',
1541
1534
  localDevAlreadyRunning: `Another ${uiCommandReference('hs project dev')} process is already running. To proceed with local development of this project, stop the existing process and re-run ${uiCommandReference('hs project dev')}.`,
1542
1535
  },
1543
1536
  examples: {
@@ -1548,9 +1541,8 @@ export const commands = {
1548
1541
  },
1549
1542
  options: {
1550
1543
  profile: 'The profile to target during local dev',
1551
- projectAccount: 'The id of the account to upload your project to. Must be used with --testing-account. Supported on platform versions 2025.2 and newer.',
1552
- testingAccount: 'The id of the account to install apps and test on. Must be used with --project-account. Supported on platform versions 2025.2 and newer.',
1553
- account: 'The id of the account to upload your project to. Unsupported on platform versions 2025.2 and newer.',
1544
+ projectAccount: 'The id of the account to upload your project to. Must be used with --testing-account.',
1545
+ testingAccount: 'The id of the account to install apps and test on. Must be used with --project-account.',
1554
1546
  port: `The port for the local dev server. Defaults to ${LOCAL_DEV_DEFAULT_PORT}.`,
1555
1547
  },
1556
1548
  },
@@ -1738,7 +1730,9 @@ export const commands = {
1738
1730
  errors: {
1739
1731
  deploy: 'Deploy error: an unknown error occurred.',
1740
1732
  noBuilds: 'Deploy error: no builds for this project were found.',
1733
+ noSuccessfulBuilds: 'Deploy error: no successful builds for this project were found.',
1741
1734
  noBuildId: 'You must specify a build to deploy',
1735
+ notSupportedForBuildVersion: `This build's platform version does not support deploy. Run ${uiCommandReference('hs project release create')} to create a release instead.`,
1742
1736
  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.`,
1743
1737
  buildIdDoesNotExist: (accountId, buildId, projectName) => `Build ${buildId} does not exist for project ${chalk.bold(projectName)}. Run ${uiCommandReference('hs project list-builds')} to view existing builds for this project.`,
1744
1738
  buildAlreadyDeployed: (accountId, buildId, projectName) => `Build ${buildId} is already deployed. ${uiLink('View project builds in HubSpot', getProjectDetailUrl(projectName, accountId))}`,
@@ -1749,7 +1743,7 @@ export const commands = {
1749
1743
  deployIssueComponentWarning: (uid, componentTypeName, message) => `- [${mapToUserFriendlyName(componentTypeName)}] ${chalk.bold('(' + uid + ')')} ${message}`,
1750
1744
  },
1751
1745
  examples: {
1752
- default: 'Deploy the latest build of the current project',
1746
+ default: 'Deploy the last successful build of the current project',
1753
1747
  withOptions: 'Deploy build 5 of the project my-project',
1754
1748
  withProfile: 'Deploy using the provided profile',
1755
1749
  },
@@ -1758,29 +1752,38 @@ export const commands = {
1758
1752
  project: 'Project name',
1759
1753
  profile: 'The profile to target with this deploy',
1760
1754
  force: 'Skip warnings and force deploy. Use this carefully as it will bypass warnings for destructive actions.',
1761
- deployLatestBuild: 'Deploy the latest build of the current project',
1755
+ deployLatestBuild: 'Deploy the last successful build of the current project',
1762
1756
  },
1763
1757
  },
1764
1758
  release: {
1765
1759
  describe: 'Manage project releases.',
1766
1760
  create: {
1767
1761
  describe: 'Create a release for a project build.',
1768
- 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.`,
1762
+ verboseDescribe: `Create a release for a project build\n\nReleases mark an uploaded build with an auto-generated semantic version tag (e.g. v1.0.0).\n\nBy default, the latest build is used. Use ${uiCommandReference('--build')} to specify a different build ID.`,
1769
1763
  confirmPrompt: (projectName, buildId) => `Create a release for project ${chalk.bold(projectName)} using build ${chalk.bold(String(buildId))}?`,
1770
1764
  success: (releaseTag, buildId) => `Release ${chalk.bold(releaseTag)} created for build ${chalk.bold(String(buildId))}.`,
1771
1765
  cancelled: 'Release creation cancelled.',
1766
+ buildIdPrompt: '[--build] Select a successful build to release:',
1767
+ noUploadMessage: 'No upload message',
1768
+ buildStatus: {
1769
+ BUILDING: 'Build in progress',
1770
+ FAILURE: 'Build failed',
1771
+ PENDING: 'Pending',
1772
+ PREPARING: 'Preparing',
1773
+ },
1774
+ uploadPrompt: (projectName) => `No successful builds for project ${chalk.bold(projectName)}. Would you like to upload it?`,
1772
1775
  errors: {
1773
1776
  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.`,
1774
- noDeployedBuild: `No deployed build found for this project. Run ${uiCommandReference('hs project deploy')} first.`,
1775
- 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.`,
1776
- buildNotDeployed: (buildId) => `Build ${chalk.bold(String(buildId))} has not been deployed. Run ${uiCommandReference('hs project deploy')} first.`,
1777
+ 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 upload')} to upload a build first.`,
1778
+ noSuccessfulBuilds: (projectName) => `No successful builds found for project ${chalk.bold(projectName)}. Run ${uiCommandReference('hs project upload')} to create a new build.`,
1779
+ incompatibleBuildVersion: `This build's platform version does not support releases. Upgrade your project to a newer platform version to use releases.`,
1777
1780
  },
1778
1781
  options: {
1779
- build: 'Build ID to release. Defaults to the latest deployed build.',
1780
- force: 'Skip confirmation prompt.',
1782
+ build: 'Build ID to release. Defaults to the latest build.',
1783
+ force: 'Skip all confirmation prompts, including automatic upload when no build exists.',
1781
1784
  },
1782
1785
  examples: {
1783
- default: 'Create a release for the latest deployed build',
1786
+ default: 'Create a release for the latest build',
1784
1787
  withBuild: 'Create a release for a specific build',
1785
1788
  },
1786
1789
  },
@@ -1906,6 +1909,7 @@ export const commands = {
1906
1909
  runCommand: (command) => `Run \`${uiCommandReference(command)}\``,
1907
1910
  autoDeployDisabled: (deployCommand) => `Automatic deploys are disabled for this project. Run ${uiCommandReference(deployCommand)} to deploy this build.`,
1908
1911
  autoDeploySkipped: (deployCommand) => `Auto-deploy was skipped for this build. Run ${uiCommandReference(deployCommand)} to deploy this build.`,
1912
+ releaseManagementRequired: (releaseCommand) => `Run ${uiCommandReference(releaseCommand)} to create a release for this build.`,
1909
1913
  },
1910
1914
  errors: {
1911
1915
  noProjectConfig: 'No project detected. Run this command from a project directory.',
@@ -3365,6 +3369,10 @@ export const lib = {
3365
3369
  handlerLogFile: {
3366
3370
  saved: (filePath) => `Debug logs can be viewed at ${filePath}`,
3367
3371
  },
3372
+ jsonSchema: {
3373
+ noSchemaForCommand: 'No schema defined for this command',
3374
+ validationFailed: 'JSON output may be missing or malformed fields. The output schema may be out of date.',
3375
+ },
3368
3376
  DevServerManager: {
3369
3377
  portConflict: (port) => `The port ${port} is already in use.`,
3370
3378
  notInitialized: 'The Dev Server Manager must be initialized before it is started.',
@@ -3522,19 +3530,6 @@ export const lib = {
3522
3530
  },
3523
3531
  },
3524
3532
  account: {
3525
- checkIfDefaultAccountIsSupported: {
3526
- publicApp: `This project contains a public app. Local development of public apps is only supported on developer accounts and developer test accounts. Change your default account using ${uiCommandReference('hs account use')}, or link a new account with ${uiAuthCommandReference()}.`,
3527
- privateApp: `This project contains a private app. Local development of private apps is not supported in developer accounts. Change your default account using ${uiCommandReference('hs account use')}, or link a new account with ${uiAuthCommandReference()}.`,
3528
- },
3529
- validateAccountOption: {
3530
- invalidPublicAppAccount: `This project contains a public app. The "--account" flag must point to a developer test account to develop this project locally. Alternatively, change your default account to an app developer account using ${uiCommandReference('hs account use')} and run ${uiCommandReference('hs project dev')} to set up a new developer test account.`,
3531
- invalidPrivateAppAccount: `This project contains a private app. The account specified with the "--account" flag points to a developer account, which do not support the local development of private apps. Update the "--account" flag to point to a standard, sandbox, or developer test account, or change your default account by running ${uiCommandReference('hs account use')}.`,
3532
- nonSandboxWarning: `Testing in a sandbox is strongly recommended. To switch the target account, select an option below or run ${uiCommandReference('hs account use')} before running the command again.`,
3533
- publicAppNonDeveloperTestAccountWarning: `Local development of public apps is only supported in ${chalk.bold('developer test accounts')}.`,
3534
- },
3535
- checkIfParentAccountIsAuthed: {
3536
- notAuthedError: (parentAccountId, accountIdentifier) => `To develop this project locally, run ${uiAuthCommandReference({ accountId: parentAccountId })} to authenticate the App Developer Account ${parentAccountId} associated with ${accountIdentifier}.`,
3537
- },
3538
3533
  selectAccountTypePrompt: {
3539
3534
  message: 'Choose the type of account to test on',
3540
3535
  developerTestAccountOption: 'Test on a developer test account (recommended)',
@@ -3542,10 +3537,7 @@ export const lib = {
3542
3537
  sandboxAccountOptionDisabled: 'Disabled - requires access to sandbox accounts',
3543
3538
  productionAccountOption: (accountId) => `<${chalk.red('!')} Test on your project account: ${uiAccountDescription(accountId, false)} ${chalk.red('!')}>`,
3544
3539
  },
3545
- confirmDefaultAccountIsTarget: {
3546
- configError: `An error occurred while reading the default account from your config. Run ${uiAuthCommandReference()} to re-auth this account`,
3547
- declineDefaultAccountExplanation: `To develop on a different account, run ${uiCommandReference('hs account use')} to change your default account, then re-run ${uiCommandReference('hs project dev')}.`,
3548
- },
3540
+ declineDefaultAccountExplanation: `To develop on a different account, run ${uiCommandReference('hs account use')} to change your default account, then re-run ${uiCommandReference('hs project dev')}.`,
3549
3541
  },
3550
3542
  },
3551
3543
  middleware: {
@@ -3868,6 +3860,7 @@ export const lib = {
3868
3860
  qa: 'Run command in QA mode',
3869
3861
  useEnv: 'Use environment variable config',
3870
3862
  jsonOutput: 'Format output as JSON',
3863
+ jsonSchema: 'Print the JSON output schema and exit',
3871
3864
  debug: 'Set log level to debug',
3872
3865
  },
3873
3866
  },
package/lib/commonOpts.js CHANGED
@@ -72,11 +72,16 @@ export function addUseEnvironmentOptions(yargs) {
72
72
  return yargs;
73
73
  }
74
74
  export function addJSONOutputOptions(yargs) {
75
- return yargs.option('json', {
75
+ yargs.option('json', {
76
76
  alias: 'format-output-as-json',
77
77
  describe: lib.commonOpts.options.jsonOutput,
78
78
  type: 'boolean',
79
79
  });
80
+ yargs.option('json-schema', {
81
+ describe: lib.commonOpts.options.jsonSchema,
82
+ type: 'boolean',
83
+ });
84
+ return yargs;
80
85
  }
81
86
  // Remove this once we've upgraded to yargs 18.0.0
82
87
  function uiBetaTagWithColor(message) {
@@ -1,4 +1,5 @@
1
1
  export declare const HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH: "HubSpot/hubspot-project-components";
2
+ export declare const MAX_LOG_FILES = 10;
2
3
  export declare const DEFAULT_PROJECT_TEMPLATE_BRANCH: "main";
3
4
  export declare const FEEDBACK_INTERVAL: 10;
4
5
  export declare const HUBSPOT_FOLDER: "@hubspot";
package/lib/constants.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export const HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH = 'HubSpot/hubspot-project-components';
2
+ export const MAX_LOG_FILES = 10;
2
3
  export const DEFAULT_PROJECT_TEMPLATE_BRANCH = 'main';
3
4
  export const FEEDBACK_INTERVAL = 10;
4
5
  export const HUBSPOT_FOLDER = '@hubspot';
@@ -0,0 +1,109 @@
1
+ import { z } from 'zod';
2
+ import { Release } from '../api/releases.js';
3
+ declare const ReleaseComponentSchema: z.ZodObject<{
4
+ buildType: z.ZodString;
5
+ buildName: z.ZodOptional<z.ZodString>;
6
+ rootPath: z.ZodOptional<z.ZodString>;
7
+ id: z.ZodOptional<z.ZodString>;
8
+ }, z.core.$strip>;
9
+ export declare const ReleaseSchema: z.ZodObject<{
10
+ releaseTag: z.ZodString;
11
+ buildId: z.ZodNumber;
12
+ createdAt: z.ZodString;
13
+ components: z.ZodOptional<z.ZodArray<z.ZodObject<{
14
+ buildType: z.ZodString;
15
+ buildName: z.ZodOptional<z.ZodString>;
16
+ rootPath: z.ZodOptional<z.ZodString>;
17
+ id: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$strip>>>;
19
+ }, z.core.$strip>;
20
+ export declare const ReleaseListSchema: z.ZodObject<{
21
+ results: z.ZodArray<z.ZodObject<{
22
+ releaseTag: z.ZodString;
23
+ buildId: z.ZodNumber;
24
+ createdAt: z.ZodString;
25
+ components: z.ZodOptional<z.ZodArray<z.ZodObject<{
26
+ buildType: z.ZodString;
27
+ buildName: z.ZodOptional<z.ZodString>;
28
+ rootPath: z.ZodOptional<z.ZodString>;
29
+ id: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strip>>>;
31
+ }, z.core.$strip>>;
32
+ paging: z.ZodOptional<z.ZodObject<{
33
+ next: z.ZodObject<{
34
+ after: z.ZodString;
35
+ }, z.core.$strip>;
36
+ }, z.core.$strip>>;
37
+ }, z.core.$strip>;
38
+ export declare const ProjectInfoSchema: z.ZodObject<{
39
+ projectName: z.ZodString;
40
+ platformVersion: z.ZodString;
41
+ projectId: z.ZodNumber;
42
+ deployedBuildId: z.ZodNumber;
43
+ autoDeployEnabled: z.ZodBoolean;
44
+ projectUrl: z.ZodOptional<z.ZodString>;
45
+ app: z.ZodOptional<z.ZodObject<{
46
+ name: z.ZodString;
47
+ id: z.ZodNumber;
48
+ uid: z.ZodString;
49
+ authType: z.ZodOptional<z.ZodString>;
50
+ distributionType: z.ZodOptional<z.ZodString>;
51
+ }, z.core.$strip>>;
52
+ components: z.ZodArray<z.ZodObject<{
53
+ uid: z.ZodString;
54
+ type: z.ZodString;
55
+ }, z.core.$strip>>;
56
+ }, z.core.$strip>;
57
+ declare const PreviewSchema: z.ZodObject<{
58
+ releaseTag: z.ZodOptional<z.ZodString>;
59
+ succeeded: z.ZodBoolean;
60
+ }, z.core.$strip>;
61
+ export declare const UploadSchema: z.ZodObject<{
62
+ buildId: z.ZodOptional<z.ZodNumber>;
63
+ deployId: z.ZodOptional<z.ZodNumber>;
64
+ preview: z.ZodOptional<z.ZodObject<{
65
+ releaseTag: z.ZodOptional<z.ZodString>;
66
+ succeeded: z.ZodBoolean;
67
+ }, z.core.$strip>>;
68
+ }, z.core.$strip>;
69
+ export declare const DeploySchema: z.ZodObject<{
70
+ deployId: z.ZodOptional<z.ZodNumber>;
71
+ }, z.core.$strip>;
72
+ export declare const InstallStatusSchema: z.ZodObject<{
73
+ appId: z.ZodOptional<z.ZodNumber>;
74
+ appUid: z.ZodString;
75
+ accountId: z.ZodNumber;
76
+ projectId: z.ZodNumber;
77
+ isInstalled: z.ZodBoolean;
78
+ isInstalledWithCurrentScopes: z.ZodBoolean;
79
+ previouslyAuthorizedScopeGroups: z.ZodArray<z.ZodObject<{
80
+ id: z.ZodNumber;
81
+ name: z.ZodString;
82
+ }, z.core.$strip>>;
83
+ }, z.core.$strip>;
84
+ export declare const InstallAppSchema: z.ZodObject<{
85
+ appId: z.ZodNumber;
86
+ appUid: z.ZodString;
87
+ accountId: z.ZodNumber;
88
+ projectId: z.ZodNumber;
89
+ installationState: z.ZodString;
90
+ installed: z.ZodBoolean;
91
+ reinstalled: z.ZodBoolean;
92
+ }, z.core.$strip>;
93
+ export declare const CreateTestAccountSchema: z.ZodObject<{
94
+ accountName: z.ZodOptional<z.ZodString>;
95
+ accountId: z.ZodOptional<z.ZodNumber>;
96
+ personalAccessKey: z.ZodOptional<z.ZodString>;
97
+ }, z.core.$strip>;
98
+ export type ReleaseComponentJsonOutput = z.infer<typeof ReleaseComponentSchema>;
99
+ export type ReleaseJsonOutput = z.infer<typeof ReleaseSchema>;
100
+ export type ReleaseListJsonOutput = z.infer<typeof ReleaseListSchema>;
101
+ export type ProjectInfoJsonOutput = z.infer<typeof ProjectInfoSchema>;
102
+ export type PreviewJsonOutput = z.infer<typeof PreviewSchema>;
103
+ export type UploadJsonOutput = z.infer<typeof UploadSchema>;
104
+ export type DeployJsonOutput = z.infer<typeof DeploySchema>;
105
+ export type InstallStatusJsonOutput = z.infer<typeof InstallStatusSchema>;
106
+ export type InstallAppJsonOutput = z.infer<typeof InstallAppSchema>;
107
+ export type CreateTestAccountJsonOutput = z.infer<typeof CreateTestAccountSchema>;
108
+ export declare function mapReleaseToJsonOutput(release: Release): ReleaseJsonOutput;
109
+ export {};
@@ -0,0 +1,94 @@
1
+ import { z } from 'zod';
2
+ const ReleaseComponentSchema = z.object({
3
+ buildType: z.string(),
4
+ buildName: z.string().optional(),
5
+ rootPath: z.string().optional(),
6
+ id: z.string().optional(),
7
+ });
8
+ export const ReleaseSchema = z.object({
9
+ releaseTag: z.string(),
10
+ buildId: z.number(),
11
+ createdAt: z.string(),
12
+ components: z.array(ReleaseComponentSchema).optional(),
13
+ });
14
+ export const ReleaseListSchema = z.object({
15
+ results: z.array(ReleaseSchema),
16
+ paging: z
17
+ .object({
18
+ next: z.object({
19
+ after: z.string(),
20
+ }),
21
+ })
22
+ .optional(),
23
+ });
24
+ export const ProjectInfoSchema = z.object({
25
+ projectName: z.string(),
26
+ platformVersion: z.string(),
27
+ projectId: z.number(),
28
+ deployedBuildId: z.number(),
29
+ autoDeployEnabled: z.boolean(),
30
+ projectUrl: z.string().optional(),
31
+ app: z
32
+ .object({
33
+ name: z.string(),
34
+ id: z.number(),
35
+ uid: z.string(),
36
+ authType: z.string().optional(),
37
+ distributionType: z.string().optional(),
38
+ })
39
+ .optional(),
40
+ components: z.array(z.object({ uid: z.string(), type: z.string() })),
41
+ });
42
+ const PreviewSchema = z.object({
43
+ releaseTag: z.string().optional(),
44
+ succeeded: z.boolean(),
45
+ });
46
+ export const UploadSchema = z.object({
47
+ buildId: z.number().optional(),
48
+ deployId: z.number().optional(),
49
+ preview: PreviewSchema.optional(),
50
+ });
51
+ export const DeploySchema = z.object({
52
+ deployId: z.number().optional(),
53
+ });
54
+ const ScopeGroupSchema = z.object({
55
+ id: z.number(),
56
+ name: z.string(),
57
+ });
58
+ export const InstallStatusSchema = z.object({
59
+ appId: z.number().optional(),
60
+ appUid: z.string(),
61
+ accountId: z.number(),
62
+ projectId: z.number(),
63
+ isInstalled: z.boolean(),
64
+ isInstalledWithCurrentScopes: z.boolean(),
65
+ previouslyAuthorizedScopeGroups: z.array(ScopeGroupSchema),
66
+ });
67
+ export const InstallAppSchema = z.object({
68
+ appId: z.number(),
69
+ appUid: z.string(),
70
+ accountId: z.number(),
71
+ projectId: z.number(),
72
+ installationState: z.string(),
73
+ installed: z.boolean(),
74
+ reinstalled: z.boolean(),
75
+ });
76
+ export const CreateTestAccountSchema = z.object({
77
+ accountName: z.string().optional(),
78
+ accountId: z.number().optional(),
79
+ personalAccessKey: z.string().optional(),
80
+ });
81
+ export function mapReleaseToJsonOutput(release) {
82
+ const { releaseTag, buildId, createdAt, components } = release;
83
+ return {
84
+ releaseTag,
85
+ buildId,
86
+ createdAt,
87
+ components: components?.map(({ buildType, buildName, rootPath, id }) => ({
88
+ buildType,
89
+ buildName,
90
+ rootPath,
91
+ id,
92
+ })),
93
+ };
94
+ }
@@ -0,0 +1,2 @@
1
+ import { type Build } from '@hubspot/local-dev-lib/types/Build';
2
+ export declare function getLastSuccessfulBuild(accountId: number, projectName: string, latestBuild?: Build): Promise<Build | undefined>;
@@ -0,0 +1,22 @@
1
+ import { fetchProjectBuilds } from '@hubspot/local-dev-lib/api/projects';
2
+ import { BUILD_STATUS } from '@hubspot/local-dev-lib/enums/build';
3
+ export async function getLastSuccessfulBuild(accountId, projectName, latestBuild) {
4
+ if (latestBuild?.status === BUILD_STATUS.SUCCESS) {
5
+ return latestBuild;
6
+ }
7
+ let after;
8
+ let hasMore = true;
9
+ while (hasMore) {
10
+ const { data: { results, paging }, } = await fetchProjectBuilds(accountId, projectName, {
11
+ limit: 100,
12
+ ...(after ? { after } : {}),
13
+ });
14
+ const successfulBuild = results.find(build => build.status === BUILD_STATUS.SUCCESS);
15
+ if (successfulBuild) {
16
+ return successfulBuild;
17
+ }
18
+ after = paging?.next?.after;
19
+ hasMore = !!after;
20
+ }
21
+ return undefined;
22
+ }
@@ -2,11 +2,11 @@ import LocalDevLogger from './LocalDevLogger.js';
2
2
  import { ExitFunction } from '../../../types/Yargs.js';
3
3
  type DevSessionManagerConstructorOptions = {
4
4
  targetTestingAccountId: number;
5
- localDevLogger?: LocalDevLogger;
5
+ localDevLogger: LocalDevLogger;
6
6
  exit: ExitFunction;
7
7
  };
8
8
  declare class DevSessionManager {
9
- localDevLogger?: LocalDevLogger;
9
+ localDevLogger: LocalDevLogger;
10
10
  targetTestingAccountId: number;
11
11
  protected devSessionId: number | undefined;
12
12
  private heartbeatInterval;
@@ -1,9 +1,7 @@
1
1
  import { getActiveServers } from '@hubspot/local-dev-lib/portManager';
2
2
  import { devSessionHeartbeat, registerDevSession, deleteDevSession, } from './helpers/devSessionsApi.js';
3
3
  import { EXIT_CODES } from '../../enums/exitCodes.js';
4
- import { uiLogger } from '../../ui/logger.js';
5
4
  import { lib } from '../../../lang/en.js';
6
- import { getErrorMessage } from '../../errorHandlers/index.js';
7
5
  class DevSessionManager {
8
6
  localDevLogger;
9
7
  targetTestingAccountId;
@@ -21,13 +19,7 @@ class DevSessionManager {
21
19
  }
22
20
  validateSessionIdExists() {
23
21
  if (!this.devSessionId) {
24
- if (this.localDevLogger) {
25
- this.localDevLogger.devSessionMissingSessionIdError();
26
- }
27
- else {
28
- // Fallback for deprecated local dev manager
29
- uiLogger.error(lib.LocalDevManager.devSession.missingSessionIdError);
30
- }
22
+ this.localDevLogger.devSessionMissingSessionIdError();
31
23
  throw new Error(lib.LocalDevManager.devSession.missingSessionIdError);
32
24
  }
33
25
  }
@@ -39,13 +31,7 @@ class DevSessionManager {
39
31
  this.devSessionId = registerDevSessionResponse.data.sessionId;
40
32
  }
41
33
  catch (e) {
42
- if (this.localDevLogger) {
43
- this.localDevLogger.devSessionRegistrationError(e);
44
- }
45
- else {
46
- // Fallback for deprecated local dev manager
47
- uiLogger.error(lib.LocalDevManager.devSession.registrationError(getErrorMessage(e)));
48
- }
34
+ this.localDevLogger.devSessionRegistrationError(e);
49
35
  return false;
50
36
  }
51
37
  try {
@@ -73,13 +59,7 @@ class DevSessionManager {
73
59
  this.heartbeatRetries++;
74
60
  return;
75
61
  }
76
- if (this.localDevLogger) {
77
- this.localDevLogger.devSessionHeartbeatError(e);
78
- }
79
- else {
80
- // Fallback for deprecated local dev manager
81
- uiLogger.error(lib.LocalDevManager.devSession.heartbeatError(getErrorMessage(e)));
82
- }
62
+ this.localDevLogger.devSessionHeartbeatError(e);
83
63
  return this.exit(EXIT_CODES.ERROR);
84
64
  }
85
65
  }, 30000);
@@ -91,13 +71,7 @@ class DevSessionManager {
91
71
  await deleteDevSession(this.targetTestingAccountId, this.devSessionId);
92
72
  }
93
73
  catch (e) {
94
- if (this.localDevLogger) {
95
- this.localDevLogger.devSessionDeletionError(e);
96
- }
97
- else {
98
- // Fallback for deprecated local dev manager
99
- uiLogger.error(lib.LocalDevManager.devSession.deletionError(getErrorMessage(e)));
100
- }
74
+ this.localDevLogger.devSessionDeletionError(e);
101
75
  return false;
102
76
  }
103
77
  }
@@ -1,13 +1,6 @@
1
1
  import { HubSpotConfigAccount } from '@hubspot/local-dev-lib/types/Accounts';
2
2
  import { Environment } from '@hubspot/local-dev-lib/types/Accounts';
3
3
  import { DeveloperTestAccount } from '@hubspot/local-dev-lib/types/developerTestAccounts.js';
4
- import { ProjectDevTargetAccountPromptResponse } from '../../../prompts/projectDevTargetAccountPrompt.js';
5
- import { ExitFunction } from '../../../../types/Yargs.js';
6
- export declare function confirmDefaultAccountIsTarget(accountConfig: HubSpotConfigAccount, exit: ExitFunction): Promise<void>;
7
- export declare function checkIfDefaultAccountIsSupported(accountConfig: HubSpotConfigAccount, hasPublicApps: boolean, exit: ExitFunction): Promise<void>;
8
- export declare function checkIfParentAccountIsAuthed(accountConfig: HubSpotConfigAccount): void;
9
- export declare function checkIfAccountFlagIsSupported(accountConfig: HubSpotConfigAccount, hasPublicApps: boolean): void;
10
- export declare function suggestRecommendedNestedAccount(accounts: HubSpotConfigAccount[], accountConfig: HubSpotConfigAccount, hasPublicApps: boolean): Promise<ProjectDevTargetAccountPromptResponse>;
11
4
  export declare function createSandboxForLocalDev(accountId: number, accountConfig: HubSpotConfigAccount, env: Environment): Promise<number>;
12
5
  export declare function createDeveloperTestAccountForLocalDev(accountId: number, accountConfig: HubSpotConfigAccount, env: Environment, useV2?: boolean): Promise<number>;
13
6
  export declare function useExistingDevTestAccount(env: Environment, account: DeveloperTestAccount): Promise<boolean>;
@@ -1,5 +1,3 @@
1
- import { HUBSPOT_ACCOUNT_TYPE_STRINGS } from '@hubspot/local-dev-lib/constants/config';
2
- import { getConfigAccountIfExists } from '@hubspot/local-dev-lib/config';
3
1
  import { HUBSPOT_ACCOUNT_TYPES } from '@hubspot/local-dev-lib/constants/config';
4
2
  import { getHubSpotWebsiteOrigin } from '@hubspot/local-dev-lib/urls';
5
3
  import { isMissingScopeError } from '@hubspot/local-dev-lib/errors/index';
@@ -7,15 +5,6 @@ import { PERSONAL_ACCESS_KEY_AUTH_METHOD } from '@hubspot/local-dev-lib/constant
7
5
  import { getSandboxUsageLimits } from '@hubspot/local-dev-lib/api/sandboxHubs';
8
6
  import { uiLogger } from '../../../ui/logger.js';
9
7
  import { lib } from '../../../../lang/en.js';
10
- import { EXIT_CODES } from '../../../enums/exitCodes.js';
11
- import { confirmDefaultAccountPrompt } from '../../../prompts/projectDevTargetAccountPrompt.js';
12
- import { isUnifiedAccount } from '../../../accountTypes.js';
13
- import { isAppDeveloperAccount } from '../../../accountTypes.js';
14
- import { isDeveloperTestAccount } from '../../../accountTypes.js';
15
- import { uiAccountDescription } from '../../../ui/index.js';
16
- import { uiLine } from '../../../ui/index.js';
17
- import { selectDeveloperTestTargetAccountPrompt } from '../../../prompts/projectDevTargetAccountPrompt.js';
18
- import { selectSandboxTargetAccountPrompt } from '../../../prompts/projectDevTargetAccountPrompt.js';
19
8
  import { validateSandboxUsageLimits } from '../../../sandboxes.js';
20
9
  import { logError } from '../../../errorHandlers/index.js';
21
10
  import { hubspotAccountNamePrompt } from '../../../prompts/accountNamePrompt.js';
@@ -25,73 +14,6 @@ import { buildDeveloperTestAccount, saveAccountToConfig, buildV2Sandbox, } from
25
14
  import { debugError } from '../../../errorHandlers/index.js';
26
15
  import { listPrompt } from '../../../prompts/promptUtils.js';
27
16
  import { confirmUseExistingDeveloperTestAccountPrompt } from '../../../prompts/projectDevTargetAccountPrompt.js';
28
- // If the user passed in the --account flag, confirm they want to use that account as
29
- // their target account, otherwise exit
30
- export async function confirmDefaultAccountIsTarget(accountConfig, exit) {
31
- if (!accountConfig.name || !accountConfig.accountType) {
32
- uiLogger.error(lib.localDevHelpers.account.confirmDefaultAccountIsTarget.configError);
33
- return exit(EXIT_CODES.ERROR);
34
- }
35
- uiLogger.log('');
36
- const useDefaultAccount = await confirmDefaultAccountPrompt(accountConfig.name, HUBSPOT_ACCOUNT_TYPE_STRINGS[accountConfig.accountType]);
37
- if (!useDefaultAccount) {
38
- uiLogger.log(lib.localDevHelpers.account.confirmDefaultAccountIsTarget
39
- .declineDefaultAccountExplanation);
40
- return exit(EXIT_CODES.SUCCESS);
41
- }
42
- }
43
- // Confirm the default account is supported for the type of apps being developed
44
- export async function checkIfDefaultAccountIsSupported(accountConfig, hasPublicApps, exit) {
45
- const defaultAccountIsUnified = await isUnifiedAccount(accountConfig);
46
- if (hasPublicApps &&
47
- !(isAppDeveloperAccount(accountConfig) ||
48
- isDeveloperTestAccount(accountConfig) ||
49
- defaultAccountIsUnified)) {
50
- uiLogger.error(lib.localDevHelpers.account.checkIfDefaultAccountIsSupported.publicApp);
51
- return exit(EXIT_CODES.SUCCESS);
52
- }
53
- else if (!hasPublicApps && isAppDeveloperAccount(accountConfig)) {
54
- uiLogger.error(lib.localDevHelpers.account.checkIfDefaultAccountIsSupported.privateApp);
55
- return exit(EXIT_CODES.SUCCESS);
56
- }
57
- }
58
- export function checkIfParentAccountIsAuthed(accountConfig) {
59
- if (!accountConfig.parentAccountId ||
60
- !getConfigAccountIfExists(accountConfig.parentAccountId)?.accountId) {
61
- throw new Error(lib.localDevHelpers.account.checkIfParentAccountIsAuthed.notAuthedError(accountConfig.parentAccountId || '', uiAccountDescription(accountConfig.accountId)));
62
- }
63
- }
64
- // Confirm the default account is a developer account if developing public apps
65
- export function checkIfAccountFlagIsSupported(accountConfig, hasPublicApps) {
66
- if (hasPublicApps) {
67
- if (!isDeveloperTestAccount(accountConfig)) {
68
- throw new Error(lib.localDevHelpers.account.validateAccountOption
69
- .invalidPublicAppAccount);
70
- }
71
- checkIfParentAccountIsAuthed(accountConfig);
72
- }
73
- else if (isAppDeveloperAccount(accountConfig)) {
74
- throw new Error(lib.localDevHelpers.account.validateAccountOption.invalidPrivateAppAccount);
75
- }
76
- }
77
- // If the user isn't using the recommended account type, prompt them to use or create one
78
- export async function suggestRecommendedNestedAccount(accounts, accountConfig, hasPublicApps) {
79
- uiLogger.log('');
80
- uiLine();
81
- if (hasPublicApps) {
82
- uiLogger.log(lib.localDevHelpers.account.validateAccountOption
83
- .publicAppNonDeveloperTestAccountWarning);
84
- }
85
- else {
86
- uiLogger.log(lib.localDevHelpers.account.validateAccountOption.nonSandboxWarning);
87
- }
88
- uiLine();
89
- uiLogger.log('');
90
- const targetAccountPrompt = hasPublicApps
91
- ? selectDeveloperTestTargetAccountPrompt
92
- : selectSandboxTargetAccountPrompt;
93
- return targetAccountPrompt(accounts, accountConfig);
94
- }
95
17
  // Create a new sandbox and return its accountId
96
18
  export async function createSandboxForLocalDev(accountId, accountConfig, env) {
97
19
  try {
@@ -166,8 +88,7 @@ export async function useExistingDevTestAccount(env, account) {
166
88
  const useExistingDevTestAcct = await confirmUseExistingDeveloperTestAccountPrompt(account);
167
89
  if (!useExistingDevTestAcct) {
168
90
  uiLogger.log('');
169
- uiLogger.log(lib.localDevHelpers.account.confirmDefaultAccountIsTarget
170
- .declineDefaultAccountExplanation);
91
+ uiLogger.log(lib.localDevHelpers.account.declineDefaultAccountExplanation);
171
92
  uiLogger.log('');
172
93
  return false;
173
94
  }
@@ -0,0 +1,4 @@
1
+ import { type Release } from '../../api/releases.js';
2
+ export declare function resolveBuildId(accountId: number, projectName: string, buildOption?: number, force?: boolean): Promise<number | null | undefined>;
3
+ export declare function validateBuildForRelease(accountId: number, projectName: string, buildId: number): Promise<boolean>;
4
+ export declare function executeRelease(accountId: number, projectName: string, buildId: number): Promise<Release>;