@hubspot/cli 8.0.11-experimental.2 → 8.0.12-experimental.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 (39) hide show
  1. package/commands/account/link.d.ts +4 -0
  2. package/commands/account/link.js +88 -0
  3. package/commands/account/unlink.d.ts +4 -0
  4. package/commands/account/unlink.js +69 -0
  5. package/commands/account.js +4 -0
  6. package/commands/project/appInstallStatus.d.ts +4 -0
  7. package/commands/project/appInstallStatus.js +132 -0
  8. package/commands/project/create.js +8 -0
  9. package/commands/project/lint.js +2 -1
  10. package/commands/project/upload.d.ts +2 -0
  11. package/commands/project/upload.js +35 -3
  12. package/commands/project.js +2 -0
  13. package/lang/en.d.ts +94 -0
  14. package/lang/en.js +103 -4
  15. package/lib/app/migrate.js +2 -1
  16. package/lib/link/accountTableUtils.d.ts +10 -0
  17. package/lib/link/accountTableUtils.js +39 -0
  18. package/lib/link/index.d.ts +14 -0
  19. package/lib/link/index.js +154 -0
  20. package/lib/link/linkUtils.d.ts +4 -0
  21. package/lib/link/linkUtils.js +24 -0
  22. package/lib/link/prompts.d.ts +7 -0
  23. package/lib/link/prompts.js +126 -0
  24. package/lib/link/renderLinkedAccountsTable.d.ts +2 -0
  25. package/lib/link/renderLinkedAccountsTable.js +14 -0
  26. package/lib/projects/ProjectLogsManager.js +4 -1
  27. package/lib/projects/preview.d.ts +7 -0
  28. package/lib/projects/preview.js +71 -0
  29. package/lib/projects/uieLinting.d.ts +8 -3
  30. package/lib/projects/uieLinting.js +48 -27
  31. package/lib/projects/upload.d.ts +1 -0
  32. package/lib/projects/upload.js +4 -3
  33. package/lib/prompts/projectsLogsPrompt.js +3 -0
  34. package/lib/prompts/promptUtils.js +1 -0
  35. package/mcp-server/server.js +35 -1
  36. package/package.json +7 -7
  37. package/types/Link.d.ts +27 -0
  38. package/types/Link.js +1 -0
  39. package/types/Prompts.d.ts +1 -0
@@ -0,0 +1,4 @@
1
+ import { YargsCommandModule } from '../../types/Yargs.js';
2
+ import { LinkArgs } from '../../types/Link.js';
3
+ declare const linkCommand: YargsCommandModule<unknown, LinkArgs>;
4
+ export default linkCommand;
@@ -0,0 +1,88 @@
1
+ import { makeYargsBuilder } from '../../lib/yargsUtils.js';
2
+ import { uiLogger } from '../../lib/ui/logger.js';
3
+ import { getAllConfigAccounts } from '@hubspot/local-dev-lib/config';
4
+ import { getCwd } from '@hubspot/local-dev-lib/path';
5
+ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
6
+ import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/local-dev-lib/config/hsSettings';
7
+ import { getDefaultAccountOverrideAccountId } from '@hubspot/local-dev-lib/config/defaultAccountOverride';
8
+ import { checkAndAddHsFolderToGitignore } from '@hubspot/local-dev-lib/gitignore';
9
+ import { DEFAULT_HS_SETTINGS_PATH, EMPTY_HS_SETTINGS_FILE, } from '@hubspot/local-dev-lib/constants/config';
10
+ import { handleLinkFlow } from '../../lib/link/index.js';
11
+ import { hasDeprecatedConfigConflict, writeLinkedSettings, } from '../../lib/link/linkUtils.js';
12
+ import { renderLinkedAccountsTable } from '../../lib/link/renderLinkedAccountsTable.js';
13
+ import { commands } from '../../lang/en.js';
14
+ import { debugError } from '../../lib/errorHandlers/index.js';
15
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
16
+ const command = 'link';
17
+ // Hide the command until we're done testing and ready to make linking GA
18
+ // const describe = commands.account.subcommands.link.describe;
19
+ const describe = undefined;
20
+ async function handler(args) {
21
+ const { exit } = args;
22
+ if (hasDeprecatedConfigConflict(args._)) {
23
+ return exit(EXIT_CODES.ERROR);
24
+ }
25
+ const existingSettings = getHsSettingsFileIfExists();
26
+ const isNewFile = existingSettings === null;
27
+ if (isNewFile) {
28
+ uiLogger.log(commands.account.subcommands.link.linkingDirectory(getCwd()));
29
+ }
30
+ else {
31
+ uiLogger.log(commands.account.subcommands.link.managingLinkedAccounts(getCwd()));
32
+ }
33
+ uiLogger.log('');
34
+ const settingsFilePath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
35
+ uiLogger.log(commands.account.subcommands.link.settingsInfo(settingsFilePath));
36
+ uiLogger.log('');
37
+ const settings = isNewFile ? EMPTY_HS_SETTINGS_FILE : existingSettings;
38
+ const accounts = getAllConfigAccounts();
39
+ const accountOverrideId = getDefaultAccountOverrideAccountId(accounts);
40
+ if (settings.accounts.length !== 0) {
41
+ await renderLinkedAccountsTable(settings);
42
+ uiLogger.log('');
43
+ }
44
+ const result = await handleLinkFlow({
45
+ settings,
46
+ accountOverrideId,
47
+ args,
48
+ });
49
+ if (result.status === 'error') {
50
+ uiLogger.error(result.reason);
51
+ return exit(EXIT_CODES.ERROR);
52
+ }
53
+ if (result.status === 'noop') {
54
+ return exit(EXIT_CODES.SUCCESS);
55
+ }
56
+ const settingsPath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
57
+ if (!writeLinkedSettings(result.settings, settingsPath)) {
58
+ return exit(EXIT_CODES.ERROR);
59
+ }
60
+ try {
61
+ checkAndAddHsFolderToGitignore(settingsPath);
62
+ }
63
+ catch (e) {
64
+ debugError(e);
65
+ }
66
+ if (isNewFile) {
67
+ uiLogger.success(commands.account.subcommands.link.success.created(settingsPath));
68
+ }
69
+ else {
70
+ uiLogger.success(commands.account.subcommands.link.shared.savedToSettings(settingsPath));
71
+ }
72
+ return exit(EXIT_CODES.SUCCESS);
73
+ }
74
+ function linkBuilder(yargs) {
75
+ yargs.example([['$0 link']]);
76
+ return yargs;
77
+ }
78
+ const builder = makeYargsBuilder(linkBuilder, command, commands.account.subcommands.link.verboseDescribe, {
79
+ useGlobalOptions: true,
80
+ useConfigOptions: true,
81
+ });
82
+ const linkCommand = {
83
+ command,
84
+ describe,
85
+ handler: makeYargsHandlerWithUsageTracking('account-link', handler),
86
+ builder,
87
+ };
88
+ export default linkCommand;
@@ -0,0 +1,4 @@
1
+ import { YargsCommandModule } from '../../types/Yargs.js';
2
+ import { LinkArgs } from '../../types/Link.js';
3
+ declare const unlinkCommand: YargsCommandModule<unknown, LinkArgs>;
4
+ export default unlinkCommand;
@@ -0,0 +1,69 @@
1
+ import { makeYargsBuilder } from '../../lib/yargsUtils.js';
2
+ import { uiLogger } from '../../lib/ui/logger.js';
3
+ import { getAllConfigAccounts } from '@hubspot/local-dev-lib/config';
4
+ import { getCwd } from '@hubspot/local-dev-lib/path';
5
+ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
6
+ import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/local-dev-lib/config/hsSettings';
7
+ import { ActionHandlers } from '../../lib/link/index.js';
8
+ import { hasDeprecatedConfigConflict, isDirectoryLinked, writeLinkedSettings, } from '../../lib/link/linkUtils.js';
9
+ import { commands } from '../../lang/en.js';
10
+ import { DEFAULT_HS_SETTINGS_PATH } from '@hubspot/local-dev-lib/constants/config';
11
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
12
+ const command = 'unlink';
13
+ // Hide the command until we're done testing and ready to make linking GA
14
+ // const describe = commands.account.subcommands.link.describe;
15
+ const describe = undefined;
16
+ async function handler(args) {
17
+ const { exit } = args;
18
+ if (hasDeprecatedConfigConflict(args._)) {
19
+ return exit(EXIT_CODES.ERROR);
20
+ }
21
+ const existingSettings = getHsSettingsFileIfExists();
22
+ if (!isDirectoryLinked(existingSettings)) {
23
+ const globalAccounts = getAllConfigAccounts();
24
+ uiLogger.log(commands.account.subcommands.link.shared.noLinkedAccounts);
25
+ uiLogger.log(commands.account.subcommands.link.shared.globalAccountsAvailable(globalAccounts.length));
26
+ uiLogger.log('');
27
+ uiLogger.log(commands.account.subcommands.link.shared.configurePrompt);
28
+ return exit(EXIT_CODES.SUCCESS);
29
+ }
30
+ uiLogger.log(commands.account.subcommands.link.managingLinkedAccounts(getCwd()));
31
+ uiLogger.log('');
32
+ const result = await ActionHandlers.unlink({
33
+ state: existingSettings,
34
+ context: {
35
+ globalAccountsList: getAllConfigAccounts(),
36
+ globalDefaultAccount: undefined,
37
+ accountOverrideId: null,
38
+ },
39
+ args,
40
+ });
41
+ if (result.status === 'error') {
42
+ uiLogger.error(result.reason);
43
+ return exit(EXIT_CODES.ERROR);
44
+ }
45
+ if (result.status === 'noop') {
46
+ return exit(EXIT_CODES.SUCCESS);
47
+ }
48
+ const settingsPath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
49
+ if (!writeLinkedSettings(result.settings, settingsPath)) {
50
+ return exit(EXIT_CODES.ERROR);
51
+ }
52
+ uiLogger.success(commands.account.subcommands.link.shared.savedToSettings(settingsPath));
53
+ return exit(EXIT_CODES.SUCCESS);
54
+ }
55
+ function unlinkBuilder(yargs) {
56
+ yargs.example([['$0 account unlink']]);
57
+ return yargs;
58
+ }
59
+ const builder = makeYargsBuilder(unlinkBuilder, command, commands.account.subcommands.unlink.verboseDescribe, {
60
+ useGlobalOptions: true,
61
+ useConfigOptions: true,
62
+ });
63
+ const unlinkCommand = {
64
+ command,
65
+ describe,
66
+ handler: makeYargsHandlerWithUsageTracking('account-unlink', handler),
67
+ builder,
68
+ };
69
+ export default unlinkCommand;
@@ -8,12 +8,16 @@ import remove from './account/remove.js';
8
8
  import clean from './account/clean.js';
9
9
  import createOverride from './account/createOverride.js';
10
10
  import removeOverride from './account/removeOverride.js';
11
+ import link from './account/link.js';
12
+ import unlink from './account/unlink.js';
11
13
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
12
14
  const command = ['account', 'accounts'];
13
15
  const describe = commands.account.describe;
14
16
  function accountBuilder(yargs) {
15
17
  yargs
16
18
  .command(auth)
19
+ .command(link)
20
+ .command(unlink)
17
21
  .command(list)
18
22
  .command(rename)
19
23
  .command(use)
@@ -0,0 +1,4 @@
1
+ import { AccountArgs, CommonArgs, ConfigArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
2
+ type ProjectInstallStatusArgs = CommonArgs & ConfigArgs & AccountArgs & JSONOutputArgs;
3
+ declare const projectInstallStatusCommand: YargsCommandModule<unknown, ProjectInstallStatusArgs>;
4
+ export default projectInstallStatusCommand;
@@ -0,0 +1,132 @@
1
+ import path from 'path';
2
+ import { fetchAppInstallationData } from '@hubspot/local-dev-lib/api/localDevAuth';
3
+ import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
4
+ import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
5
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
6
+ import { translateForLocalDev } from '@hubspot/project-parsing-lib/translate';
7
+ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
8
+ import { makeYargsBuilder } from '../../lib/yargsUtils.js';
9
+ import { uiLogger } from '../../lib/ui/logger.js';
10
+ import { ApiErrorContext, debugError, logError, } from '../../lib/errorHandlers/index.js';
11
+ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
12
+ import { commands } from '../../lang/en.js';
13
+ import { getProjectConfig } from '../../lib/projects/config.js';
14
+ import { isAppIRNode } from '../../lib/projects/structure.js';
15
+ import { APP_AUTH_TYPES } from '../../lib/constants.js';
16
+ const command = 'app-install-status';
17
+ const describe = commands.project.installStatus.describe;
18
+ async function handler(args) {
19
+ const { derivedAccountId, formatOutputAsJson, exit } = args;
20
+ const { projectConfig, projectDir } = await getProjectConfig();
21
+ if (!projectConfig || !projectDir) {
22
+ uiLogger.error(commands.project.installStatus.errors.noProjectConfig);
23
+ return exit(EXIT_CODES.ERROR);
24
+ }
25
+ if (isLegacyProject(projectConfig.platformVersion)) {
26
+ uiLogger.error(commands.project.installStatus.errors.unsupportedPlatformVersion(projectConfig.platformVersion));
27
+ return exit(EXIT_CODES.ERROR);
28
+ }
29
+ let appNode;
30
+ try {
31
+ const { intermediateNodesIndexedByUid } = await translateForLocalDev({
32
+ projectSourceDir: path.join(projectDir, projectConfig.srcDir),
33
+ platformVersion: projectConfig.platformVersion,
34
+ accountId: derivedAccountId,
35
+ }, { skipValidation: true });
36
+ appNode = Object.values(intermediateNodesIndexedByUid).find(isAppIRNode);
37
+ }
38
+ catch (error) {
39
+ debugError(error);
40
+ uiLogger.error(commands.project.installStatus.errors.failedToParseProject);
41
+ return exit(EXIT_CODES.ERROR);
42
+ }
43
+ if (!appNode) {
44
+ uiLogger.error(commands.project.installStatus.errors.noAppInProject);
45
+ return exit(EXIT_CODES.ERROR);
46
+ }
47
+ if (appNode.config.auth.type.toLowerCase() !== APP_AUTH_TYPES.STATIC) {
48
+ uiLogger.error(commands.project.installStatus.errors.unsupportedAuthType(appNode.config.auth.type));
49
+ return exit(EXIT_CODES.ERROR);
50
+ }
51
+ let projectId;
52
+ try {
53
+ const response = await fetchProject(derivedAccountId, projectConfig.name);
54
+ projectId = response.data.id;
55
+ }
56
+ catch (error) {
57
+ logError(error, new ApiErrorContext({
58
+ accountId: derivedAccountId,
59
+ projectName: projectConfig.name,
60
+ }));
61
+ return exit(EXIT_CODES.ERROR);
62
+ }
63
+ let isInstalledWithScopeGroups = false;
64
+ let previouslyAuthorizedScopeGroups = [];
65
+ let appId;
66
+ try {
67
+ const response = await fetchAppInstallationData(derivedAccountId, projectId, appNode.uid, appNode.config.auth.requiredScopes, appNode.config.auth.optionalScopes);
68
+ isInstalledWithScopeGroups = response.data.isInstalledWithScopeGroups;
69
+ previouslyAuthorizedScopeGroups =
70
+ response.data.previouslyAuthorizedScopeGroups;
71
+ appId = response.data.appId;
72
+ }
73
+ catch (error) {
74
+ if (!isHubSpotHttpError(error) || error.status !== 404) {
75
+ logError(error, new ApiErrorContext({
76
+ accountId: derivedAccountId,
77
+ projectName: projectConfig.name,
78
+ }));
79
+ return exit(EXIT_CODES.ERROR);
80
+ }
81
+ }
82
+ const isInstalled = isInstalledWithScopeGroups || previouslyAuthorizedScopeGroups.length > 0;
83
+ if (formatOutputAsJson) {
84
+ uiLogger.json({
85
+ appId,
86
+ appUid: appNode.uid,
87
+ accountId: derivedAccountId,
88
+ projectId,
89
+ isInstalled,
90
+ isInstalledWithCurrentScopes: isInstalledWithScopeGroups,
91
+ previouslyAuthorizedScopeGroups,
92
+ });
93
+ return exit(isInstalled ? EXIT_CODES.SUCCESS : EXIT_CODES.WARNING);
94
+ }
95
+ if (isInstalled) {
96
+ if (isInstalledWithScopeGroups) {
97
+ uiLogger.success(commands.project.installStatus.success.installed(appNode.config.name, derivedAccountId));
98
+ }
99
+ else {
100
+ uiLogger.success(commands.project.installStatus.success.installedWithOutdatedScopes(appNode.config.name, derivedAccountId));
101
+ }
102
+ return exit(EXIT_CODES.SUCCESS);
103
+ }
104
+ uiLogger.log(commands.project.installStatus.notInstalled(appNode.config.name, derivedAccountId));
105
+ return exit(EXIT_CODES.WARNING);
106
+ }
107
+ function projectInstallStatusBuilder(yargs) {
108
+ yargs.example([
109
+ [
110
+ '$0 project app-install-status',
111
+ commands.project.installStatus.examples.default,
112
+ ],
113
+ [
114
+ '$0 project app-install-status --json',
115
+ commands.project.installStatus.examples.json,
116
+ ],
117
+ ]);
118
+ return yargs;
119
+ }
120
+ const builder = makeYargsBuilder(projectInstallStatusBuilder, command, describe, {
121
+ useGlobalOptions: true,
122
+ useConfigOptions: true,
123
+ useAccountOptions: true,
124
+ useJSONOutputOptions: true,
125
+ });
126
+ const projectInstallStatusCommand = {
127
+ command,
128
+ describe,
129
+ handler: makeYargsHandlerWithUsageTracking('project-app-install-status', handler),
130
+ builder,
131
+ };
132
+ export default projectInstallStatusCommand;
@@ -19,8 +19,15 @@ import { updateHsMetaFilesWithAutoGeneratedFields } from '../../lib/projects/com
19
19
  import SpinniesManager from '../../lib/ui/SpinniesManager.js';
20
20
  const command = ['create', 'init'];
21
21
  const describe = commands.project.create.describe;
22
+ const BETA_VERSIONS = [
23
+ PLATFORM_VERSIONS.v2026_09_BETA,
24
+ PLATFORM_VERSIONS.v2026_03_BETA,
25
+ ];
22
26
  async function handler(args) {
23
27
  const { platformVersion, templateSource, exit, addUsageMetadata } = args;
28
+ if (BETA_VERSIONS.includes(platformVersion)) {
29
+ uiLogger.warn(commands.project.create.warnings.betaPlatformVersion(platformVersion));
30
+ }
24
31
  if (templateSource && !templateSource.includes('/')) {
25
32
  uiLogger.error(commands.project.create.errors.invalidTemplateSource);
26
33
  return exit(EXIT_CODES.ERROR);
@@ -128,6 +135,7 @@ function projectCreateBuilder(yargs) {
128
135
  PLATFORM_VERSIONS.v2025_2,
129
136
  PLATFORM_VERSIONS.v2026_03_BETA,
130
137
  PLATFORM_VERSIONS.v2026_03,
138
+ PLATFORM_VERSIONS.v2026_09_BETA,
131
139
  ],
132
140
  default: PLATFORM_VERSIONS.v2026_03,
133
141
  },
@@ -117,9 +117,10 @@ async function handler(args) {
117
117
  SpinniesManager.add('lintConfigCreate', {
118
118
  text: commands.project.lint.loading.creatingConfig,
119
119
  });
120
+ const platformVersion = projectConfig.projectConfig?.platformVersion ?? null;
120
121
  const createdConfigs = [];
121
122
  for (const location of locationsNeedingConfig) {
122
- const configPath = createEslintConfig(location);
123
+ const configPath = await createEslintConfig(location, platformVersion);
123
124
  createdConfigs.push(configPath);
124
125
  }
125
126
  SpinniesManager.succeed('lintConfigCreate');
@@ -5,6 +5,8 @@ export type ProjectUploadArgs = CommonArgs & JSONOutputArgs & {
5
5
  m: string;
6
6
  skipValidation: boolean;
7
7
  profile?: string;
8
+ preview: boolean;
9
+ target?: number;
8
10
  };
9
11
  declare const projectUploadCommand: YargsCommandModule<unknown, ProjectUploadArgs>;
10
12
  export default projectUploadCommand;
@@ -8,7 +8,8 @@ import { logFeedbackMessage } from '../../lib/projects/ui.js';
8
8
  import { handleProjectUpload } from '../../lib/projects/upload.js';
9
9
  import { loadAndValidateProfile } from '../../lib/projects/projectProfiles.js';
10
10
  import { displayWarnLogs, pollProjectBuildAndDeploy, } from '../../lib/projects/pollProjectBuildAndDeploy.js';
11
- import { commands } from '../../lang/en.js';
11
+ import { triggerAndPollPreview } from '../../lib/projects/preview.js';
12
+ import { commands, lib } from '../../lang/en.js';
12
13
  import { PROJECT_ERROR_TYPES } from '../../lib/constants.js';
13
14
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
14
15
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
@@ -18,7 +19,7 @@ import { projectProfilePrompt } from '../../lib/prompts/projectProfilePrompt.js'
18
19
  const command = 'upload';
19
20
  const describe = commands.project.upload.describe;
20
21
  async function handler(args) {
21
- const { forceCreate, message, derivedAccountId, skipValidation, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, exit, addUsageMetadata, } = args;
22
+ const { forceCreate, message, derivedAccountId, skipValidation, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, preview, target: targetPortalId, exit, addUsageMetadata, } = args;
22
23
  const jsonOutput = {};
23
24
  const { projectConfig, projectDir } = await getProjectConfig();
24
25
  try {
@@ -56,7 +57,7 @@ async function handler(args) {
56
57
  assetType: projectConfig.platformVersion,
57
58
  });
58
59
  try {
59
- const { result, uploadError } = await handleProjectUpload({
60
+ const { result, uploadError, projectId } = await handleProjectUpload({
60
61
  accountId: targetAccountId,
61
62
  projectConfig,
62
63
  projectDir,
@@ -90,6 +91,23 @@ async function handler(args) {
90
91
  logFeedbackMessage(result.buildId);
91
92
  await displayWarnLogs(targetAccountId, projectConfig.name, result.buildId);
92
93
  }
94
+ if (result && result.succeeded && preview && targetPortalId) {
95
+ if (!projectId) {
96
+ uiLogger.warn(lib.projectPreview.missingProjectId);
97
+ }
98
+ else {
99
+ const previewResult = await triggerAndPollPreview(targetAccountId, projectId, result.buildId, targetPortalId);
100
+ if (!previewResult.succeeded) {
101
+ uiLogger.warn(lib.projectPreview.warning);
102
+ }
103
+ if (formatOutputAsJson) {
104
+ jsonOutput.preview = {
105
+ releaseTag: previewResult.releaseTag,
106
+ succeeded: previewResult.succeeded,
107
+ };
108
+ }
109
+ }
110
+ }
93
111
  if (result && result.succeeded && formatOutputAsJson) {
94
112
  jsonOutput.buildId = result.buildId;
95
113
  if (result.deployResult) {
@@ -132,14 +150,28 @@ function projectUploadBuilder(yargs) {
132
150
  alias: 'p',
133
151
  describe: commands.project.upload.options.profile.describe,
134
152
  },
153
+ preview: {
154
+ describe: commands.project.upload.options.preview.describe,
155
+ type: 'boolean',
156
+ default: false,
157
+ },
158
+ target: {
159
+ describe: commands.project.upload.options.target.describe,
160
+ type: 'number',
161
+ },
135
162
  });
136
163
  yargs.conflicts('profile', 'account');
164
+ yargs.implies('preview', 'target');
137
165
  yargs.example([
138
166
  ['$0 project upload', commands.project.upload.examples.default],
139
167
  [
140
168
  '$0 project upload --profile=profileName',
141
169
  commands.project.upload.examples.withProfile,
142
170
  ],
171
+ [
172
+ '$0 project upload --preview --target=12345',
173
+ commands.project.upload.examples.withPreview,
174
+ ],
143
175
  ]);
144
176
  return yargs;
145
177
  }
@@ -19,6 +19,7 @@ import projectValidate from './project/validate.js';
19
19
  import list from './project/list.js';
20
20
  import info from './project/info.js';
21
21
  import deleteProject from './project/delete.js';
22
+ import appInstallStatus from './project/appInstallStatus.js';
22
23
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
23
24
  import { getProjectConfig } from '../lib/projects/config.js';
24
25
  import { isSupportedPlatformVersion, LATEST_SUPPORTED_PLATFORM_VERSION, } from '@hubspot/project-parsing-lib/projects';
@@ -66,6 +67,7 @@ function projectBuilder(yargs) {
66
67
  .command(updateDeps)
67
68
  .command(profile)
68
69
  .command(projectValidate)
70
+ .command(appInstallStatus)
69
71
  .demandCommand(1, '');
70
72
  return yargs;
71
73
  }
package/lang/en.d.ts CHANGED
@@ -178,6 +178,58 @@ export declare const commands: {
178
178
  defaultAccountUpdated: (accountName: string) => string;
179
179
  };
180
180
  };
181
+ link: {
182
+ describe: string;
183
+ verboseDescribe: string;
184
+ shared: {
185
+ noLinkedAccounts: string;
186
+ globalAccountsAvailable: (count: number) => string;
187
+ configurePrompt: string;
188
+ deprecatedConfigNotSupported: (command: string) => string;
189
+ writeSettingsFailed: (path: string, err: unknown) => string;
190
+ savedToSettings: (path: string) => string;
191
+ };
192
+ linkingDirectory: (dir: string) => string;
193
+ managingLinkedAccounts: (dir: string) => string;
194
+ settingsInfo: (path: string) => string;
195
+ success: {
196
+ created: (path: string) => string;
197
+ };
198
+ errors: {
199
+ authFailed: string;
200
+ };
201
+ events: {
202
+ accountsLinked: (count: number) => string;
203
+ accountsUnlinked: (count: number) => string;
204
+ overrideAccountDetected: (accountId: number) => string;
205
+ defaultAccountSet: (accountId: number) => string;
206
+ defaultAccountRemoved: (isSelectionRequired: boolean) => string;
207
+ defaultAccountRemains: (accountId: number) => string;
208
+ updatedLinkedAccounts: string;
209
+ noAccountsLinked: string;
210
+ overrideFileRemoved: string;
211
+ invalidDefaultAccount: (accountId: number) => string;
212
+ };
213
+ prompts: {
214
+ howToProceed: string;
215
+ whatToDo: string;
216
+ linkExisting: string;
217
+ authenticateNew: string;
218
+ cancel: string;
219
+ selectDefault: string;
220
+ selectToLink: string;
221
+ selectToUnlink: string;
222
+ alreadyLinked: string;
223
+ fromHsAccount: string;
224
+ newlyAuthenticated: string;
225
+ mustSelectOne: string;
226
+ keepAsDefault: string;
227
+ };
228
+ };
229
+ unlink: {
230
+ describe: string;
231
+ verboseDescribe: string;
232
+ };
181
233
  remove: {
182
234
  describe: string;
183
235
  logs: {
@@ -1458,6 +1510,9 @@ export declare const commands: {
1458
1510
  failedToFetchProjectList: string;
1459
1511
  cannotNestProjects: (projectDir: string) => string;
1460
1512
  };
1513
+ warnings: {
1514
+ betaPlatformVersion: (platformVersion: string) => string;
1515
+ };
1461
1516
  logs: {
1462
1517
  success: (projectName: string, projectDest: string) => string;
1463
1518
  };
@@ -1684,6 +1739,7 @@ export declare const commands: {
1684
1739
  noFunctionsLinkText: string;
1685
1740
  noFunctionsInProject: string;
1686
1741
  noFunctionWithName: (name: string) => string;
1742
+ functionNameRequired: string;
1687
1743
  functionNotDeployed: (name: string) => string;
1688
1744
  projectLogsManagerNotInitialized: string;
1689
1745
  noDeployedBuild: string;
@@ -1729,6 +1785,7 @@ export declare const commands: {
1729
1785
  examples: {
1730
1786
  default: string;
1731
1787
  withProfile: string;
1788
+ withPreview: string;
1732
1789
  };
1733
1790
  logs: {
1734
1791
  buildSucceeded: (buildId: number) => string;
@@ -1750,6 +1807,12 @@ export declare const commands: {
1750
1807
  profile: {
1751
1808
  describe: string;
1752
1809
  };
1810
+ preview: {
1811
+ describe: string;
1812
+ };
1813
+ target: {
1814
+ describe: string;
1815
+ };
1753
1816
  };
1754
1817
  };
1755
1818
  watch: {
@@ -1876,6 +1939,8 @@ export declare const commands: {
1876
1939
  }[]) => string;
1877
1940
  createEslintConfigPrompt: (directories: string[]) => string;
1878
1941
  eslintConfigCreated: (configPath: string) => string;
1942
+ createEslintConfigRequiresV2Platform: (platformVersion?: string | null) => string;
1943
+ failedToFetchRemoteEslintConfig: (platformVersion: string) => string;
1879
1944
  failedToCreateEslintConfig: (configPath: string) => string;
1880
1945
  eslintConfigRequired: string;
1881
1946
  };
@@ -2009,6 +2074,25 @@ export declare const commands: {
2009
2074
  force: string;
2010
2075
  };
2011
2076
  };
2077
+ installStatus: {
2078
+ describe: string;
2079
+ examples: {
2080
+ default: string;
2081
+ json: string;
2082
+ };
2083
+ errors: {
2084
+ noProjectConfig: string;
2085
+ unsupportedPlatformVersion: (platformVersion: string) => string;
2086
+ failedToParseProject: string;
2087
+ noAppInProject: string;
2088
+ unsupportedAuthType: (authType: string) => string;
2089
+ };
2090
+ success: {
2091
+ installed: (appName: string, accountId: number) => string;
2092
+ installedWithOutdatedScopes: (appName: string, accountId: number) => string;
2093
+ };
2094
+ notInstalled: (appName: string, accountId: number) => string;
2095
+ };
2012
2096
  };
2013
2097
  sandbox: {
2014
2098
  describe: string;
@@ -3290,6 +3374,16 @@ export declare const lib: {
3290
3374
  updatedFileDependency: (packageName: string, relativePath: string) => string;
3291
3375
  };
3292
3376
  };
3377
+ projectPreview: {
3378
+ triggeringPreview: (buildId: number, targetPortalId: number) => string;
3379
+ pollingStatus: (releaseTag: string, targetPortalId: number) => string;
3380
+ succeeded: (releaseTag: string, targetPortalId: number) => string;
3381
+ triggerFailed: string;
3382
+ pollFailed: string;
3383
+ timeout: string;
3384
+ warning: string;
3385
+ missingProjectId: string;
3386
+ };
3293
3387
  importData: {
3294
3388
  errors: {
3295
3389
  incorrectAccountType: (derivedAccountId: number) => string;