@hubspot/cli 7.6.0-beta.10 → 7.6.0-beta.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/app/__tests__/migrate.test.js +1 -0
- package/commands/getStarted.js +70 -22
- package/commands/mcp/setup.d.ts +0 -1
- package/commands/mcp/setup.js +3 -11
- package/commands/project/__tests__/add.test.js +64 -0
- package/commands/project/__tests__/create.test.js +57 -0
- package/commands/project/__tests__/deploy.test.js +3 -2
- package/commands/project/__tests__/devUnifiedFlow.test.js +14 -5
- package/commands/project/add.d.ts +1 -1
- package/commands/project/add.js +3 -5
- package/commands/project/create.js +7 -2
- package/commands/project/deploy.js +9 -61
- package/commands/project/dev/index.js +33 -13
- package/commands/project/dev/unifiedFlow.js +8 -7
- package/commands/project/upload.js +2 -2
- package/commands/project/validate.js +1 -1
- package/commands/project/watch.js +2 -2
- package/lang/en.d.ts +36 -13
- package/lang/en.js +49 -25
- package/lang/en.lyaml +12 -12
- package/lib/__tests__/hasFeature.test.js +145 -7
- package/lib/__tests__/importData.test.js +1 -1
- package/lib/app/migrate.js +9 -2
- package/lib/constants.d.ts +2 -0
- package/lib/constants.js +2 -0
- package/lib/errorHandlers/index.d.ts +4 -0
- package/lib/errorHandlers/index.js +1 -1
- package/lib/hasFeature.js +6 -0
- package/lib/importData.js +1 -1
- package/lib/mcp/setup.d.ts +0 -2
- package/lib/mcp/setup.js +4 -29
- package/lib/projects/__tests__/AppDevModeInterface.test.js +72 -44
- package/lib/projects/__tests__/LocalDevProcess.test.js +1 -0
- package/lib/projects/__tests__/components.test.js +164 -7
- package/lib/projects/__tests__/deploy.test.js +164 -0
- package/lib/projects/__tests__/platformVersion.test.d.ts +1 -0
- package/lib/projects/__tests__/{buildAndDeploy.test.js → platformVersion.test.js} +2 -2
- package/lib/projects/add/__tests__/legacyAddComponent.test.js +49 -6
- package/lib/projects/add/__tests__/v3AddComponent.test.js +142 -8
- package/lib/projects/add/legacyAddComponent.d.ts +1 -1
- package/lib/projects/add/legacyAddComponent.js +5 -1
- package/lib/projects/add/v3AddComponent.d.ts +2 -1
- package/lib/projects/add/v3AddComponent.js +22 -5
- package/lib/projects/components.d.ts +1 -0
- package/lib/projects/components.js +27 -1
- package/lib/projects/create/__tests__/v3.test.js +97 -9
- package/lib/projects/create/index.js +2 -2
- package/lib/projects/create/legacy.js +1 -1
- package/lib/projects/create/v3.d.ts +2 -2
- package/lib/projects/create/v3.js +35 -12
- package/lib/projects/deploy.d.ts +13 -0
- package/lib/projects/deploy.js +63 -0
- package/lib/projects/localDev/AppDevModeInterface.d.ts +5 -3
- package/lib/projects/localDev/AppDevModeInterface.js +132 -48
- package/lib/projects/localDev/DevServerManagerV2.js +1 -0
- package/lib/projects/localDev/LocalDevProcess.js +3 -1
- package/lib/projects/localDev/LocalDevState.d.ts +5 -2
- package/lib/projects/localDev/LocalDevState.js +9 -1
- package/lib/projects/localDev/helpers/account.js +2 -2
- package/lib/projects/localDev/helpers/project.d.ts +2 -2
- package/lib/projects/localDev/helpers/project.js +6 -8
- package/lib/projects/platformVersion.d.ts +1 -0
- package/lib/projects/platformVersion.js +10 -0
- package/lib/projects/{buildAndDeploy.d.ts → pollProjectBuildAndDeploy.d.ts} +0 -1
- package/lib/projects/{buildAndDeploy.js → pollProjectBuildAndDeploy.js} +0 -10
- package/lib/projects/upload.js +1 -1
- package/lib/projects/urls.d.ts +1 -0
- package/lib/projects/urls.js +3 -0
- package/lib/prompts/__tests__/projectAddPrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/projectAddPrompt.test.js +143 -0
- package/lib/prompts/__tests__/selectProjectTemplatePrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/selectProjectTemplatePrompt.test.js +160 -0
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +1 -0
- package/lib/prompts/importDataFilePathPrompt.js +4 -2
- package/lib/prompts/installAppPrompt.d.ts +6 -1
- package/lib/prompts/installAppPrompt.js +6 -1
- package/lib/prompts/projectAddPrompt.js +1 -1
- package/lib/prompts/projectDevTargetAccountPrompt.js +1 -0
- package/lib/prompts/promptUtils.d.ts +7 -1
- package/lib/prompts/promptUtils.js +14 -1
- package/lib/prompts/selectProjectTemplatePrompt.js +1 -1
- package/lib/ui/index.js +3 -6
- package/mcp-server/server.js +2 -1
- package/mcp-server/tools/cms/HsCreateFunctionTool.d.ts +32 -0
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +96 -0
- package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +38 -0
- package/mcp-server/tools/cms/HsCreateModuleTool.js +118 -0
- package/mcp-server/tools/cms/HsCreateTemplateTool.d.ts +26 -0
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +75 -0
- package/mcp-server/tools/cms/HsFunctionLogsTool.d.ts +32 -0
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +76 -0
- package/mcp-server/tools/cms/HsListFunctionsTool.d.ts +23 -0
- package/mcp-server/tools/cms/HsListFunctionsTool.js +58 -0
- package/mcp-server/tools/cms/HsListTool.d.ts +23 -0
- package/mcp-server/tools/cms/HsListTool.js +58 -0
- package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +251 -0
- package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.js +224 -0
- package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.js +206 -0
- package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.js +183 -0
- package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.js +120 -0
- package/mcp-server/tools/cms/__tests__/HsListTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsListTool.test.js +120 -0
- package/mcp-server/tools/index.d.ts +1 -0
- package/mcp-server/tools/index.js +16 -0
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +3 -3
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +3 -3
- package/mcp-server/tools/project/CreateProjectTool.d.ts +3 -3
- package/mcp-server/tools/project/CreateProjectTool.js +5 -5
- package/mcp-server/tools/project/DeployProjectTool.js +1 -1
- package/mcp-server/tools/project/DocFetchTool.js +3 -3
- package/mcp-server/tools/project/DocsSearchTool.js +3 -3
- package/mcp-server/tools/project/GetConfigValuesTool.js +4 -4
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +1 -1
- package/mcp-server/tools/project/UploadProjectTools.js +2 -2
- package/mcp-server/tools/project/ValidateProjectTool.js +1 -1
- package/mcp-server/tools/project/__tests__/AddFeatureToProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/DeployProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +3 -3
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +3 -3
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +1 -1
- package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +1 -1
- package/mcp-server/tools/project/constants.d.ts +1 -1
- package/mcp-server/tools/project/constants.js +14 -6
- package/package.json +5 -4
- package/types/LocalDev.d.ts +2 -1
- package/types/Projects.d.ts +1 -0
- package/types/Prompts.d.ts +1 -0
- package/ui/components/BoxWithTitle.d.ts +8 -0
- package/ui/components/BoxWithTitle.js +9 -0
- package/ui/components/HorizontalSelectPrompt.d.ts +8 -0
- package/ui/components/HorizontalSelectPrompt.js +30 -0
- package/ui/components/StatusMessageBoxes.d.ts +12 -0
- package/ui/components/StatusMessageBoxes.js +31 -0
- package/ui/lib/ui-testing-utils.d.ts +9 -0
- package/ui/lib/ui-testing-utils.js +47 -0
- package/ui/lib/useTerminalSize.d.ts +13 -0
- package/ui/lib/useTerminalSize.js +31 -0
- package/ui/styles.d.ts +18 -0
- package/ui/styles.js +18 -0
- package/ui/views/UiSandbox.d.ts +5 -0
- package/ui/views/UiSandbox.js +25 -0
- /package/lib/projects/__tests__/{buildAndDeploy.test.d.ts → deploy.test.d.ts} +0 -0
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
|
|
2
2
|
import { getAccountConfig } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
4
|
-
import { useV3Api } from '../../lib/projects/
|
|
4
|
+
import { useV3Api } from '../../lib/projects/platformVersion.js';
|
|
5
5
|
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
6
6
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
7
7
|
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
8
|
-
import { pollDeployStatus } from '../../lib/projects/buildAndDeploy.js';
|
|
9
8
|
import { projectNamePrompt } from '../../lib/prompts/projectNamePrompt.js';
|
|
10
9
|
import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
11
10
|
import { uiBetaTag, uiLine } from '../../lib/ui/index.js';
|
|
@@ -13,54 +12,11 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
|
13
12
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
14
13
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
15
14
|
import { loadProfile, logProfileFooter, logProfileHeader, exitIfUsingProfiles, } from '../../lib/projectProfiles.js';
|
|
16
|
-
import {
|
|
15
|
+
import { PROJECT_DEPLOY_TEXT } from '../../lib/constants.js';
|
|
17
16
|
import { commands } from '../../lang/en.js';
|
|
17
|
+
import { handleProjectDeploy, validateBuildIdForDeploy, logDeployErrors, } from '../../lib/projects/deploy.js';
|
|
18
18
|
const command = 'deploy';
|
|
19
19
|
const describe = uiBetaTag(commands.project.deploy.describe, false);
|
|
20
|
-
function validateBuildId(buildId, deployedBuildId, latestBuildId, projectName, accountId) {
|
|
21
|
-
if (Number(buildId) > latestBuildId) {
|
|
22
|
-
return commands.project.deploy.errors.buildIdDoesNotExist(accountId, buildId, projectName);
|
|
23
|
-
}
|
|
24
|
-
if (Number(buildId) === deployedBuildId) {
|
|
25
|
-
return commands.project.deploy.errors.buildAlreadyDeployed(accountId, buildId, projectName);
|
|
26
|
-
}
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
function logDeployErrors(errorData) {
|
|
30
|
-
uiLogger.error(errorData.message);
|
|
31
|
-
errorData.errors.forEach(err => {
|
|
32
|
-
// This is how the pre-deploy check manifests itself in < 2025.2 projects
|
|
33
|
-
if (err.subCategory === PROJECT_ERROR_TYPES.DEPLOY_CONTAINS_REMOVALS) {
|
|
34
|
-
uiLogger.log(commands.project.deploy.errors.deployContainsRemovals(err.context.COMPONENT_NAME));
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
uiLogger.log(err.message);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
function handleBlockedDeploy(deployResp) {
|
|
42
|
-
const deployCanBeForced = deployResp.issues.every(issue => issue.blockingMessages.every(message => message.isWarning));
|
|
43
|
-
uiLogger.log('');
|
|
44
|
-
if (deployCanBeForced) {
|
|
45
|
-
uiLogger.warn(commands.project.deploy.errors.deployWarningsHeader);
|
|
46
|
-
uiLogger.log('');
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
uiLogger.error(commands.project.deploy.errors.deployBlockedHeader);
|
|
50
|
-
uiLogger.log('');
|
|
51
|
-
}
|
|
52
|
-
deployResp.issues.forEach(issue => {
|
|
53
|
-
if (issue.blockingMessages.length > 0) {
|
|
54
|
-
issue.blockingMessages.forEach(message => {
|
|
55
|
-
uiLogger.log(commands.project.deploy.errors.deployIssueComponentWarning(issue.uid, issue.componentTypeName, message.message));
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
uiLogger.log(commands.project.deploy.errors.deployIssueComponentGeneric(issue.uid, issue.componentTypeName));
|
|
60
|
-
}
|
|
61
|
-
uiLogger.log('');
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
20
|
async function handler(args) {
|
|
65
21
|
const { derivedAccountId, project: projectOption, buildId: buildIdOption, force: forceOption, deployLatestBuild: deployLatestBuildOption, json: formatOutputAsJson, } = args;
|
|
66
22
|
const accountConfig = getAccountConfig(derivedAccountId);
|
|
@@ -105,7 +61,7 @@ async function handler(args) {
|
|
|
105
61
|
return process.exit(EXIT_CODES.ERROR);
|
|
106
62
|
}
|
|
107
63
|
if (buildIdToDeploy) {
|
|
108
|
-
const validationResult =
|
|
64
|
+
const validationResult = validateBuildIdForDeploy(buildIdToDeploy, deployedBuildId, latestBuild.buildId, projectName, targetAccountId);
|
|
109
65
|
if (validationResult !== true) {
|
|
110
66
|
uiLogger.error(validationResult.toString());
|
|
111
67
|
return process.exit(EXIT_CODES.ERROR);
|
|
@@ -122,7 +78,7 @@ async function handler(args) {
|
|
|
122
78
|
default: latestBuild.buildId === deployedBuildId
|
|
123
79
|
? undefined
|
|
124
80
|
: latestBuild.buildId,
|
|
125
|
-
validate: buildId =>
|
|
81
|
+
validate: buildId => validateBuildIdForDeploy(buildId, deployedBuildId, latestBuild.buildId, projectName, targetAccountId),
|
|
126
82
|
});
|
|
127
83
|
buildIdToDeploy = deployBuildIdPromptResponse.buildId;
|
|
128
84
|
}
|
|
@@ -131,21 +87,13 @@ async function handler(args) {
|
|
|
131
87
|
uiLogger.error(commands.project.deploy.errors.noBuildId);
|
|
132
88
|
return process.exit(EXIT_CODES.ERROR);
|
|
133
89
|
}
|
|
134
|
-
const
|
|
135
|
-
if (!
|
|
136
|
-
if (deployResp?.buildResultType === 'DEPLOY_BLOCKED') {
|
|
137
|
-
handleBlockedDeploy(deployResp);
|
|
138
|
-
process.exit(EXIT_CODES.ERROR);
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
uiLogger.error(commands.project.deploy.errors.deploy);
|
|
142
|
-
}
|
|
90
|
+
const deployResult = await handleProjectDeploy(targetAccountId, projectName, buildIdToDeploy, useV3Api(projectConfig?.platformVersion), forceOption);
|
|
91
|
+
if (!deployResult) {
|
|
143
92
|
return process.exit(EXIT_CODES.ERROR);
|
|
144
93
|
}
|
|
145
94
|
else if (formatOutputAsJson) {
|
|
146
|
-
jsonOutput.deployId =
|
|
95
|
+
jsonOutput.deployId = deployResult.deployId;
|
|
147
96
|
}
|
|
148
|
-
const deployResult = await pollDeployStatus(targetAccountId, projectName, Number(deployResp.id), buildIdToDeploy);
|
|
149
97
|
if (deployResult.status === PROJECT_DEPLOY_TEXT.STATES.SUCCESS) {
|
|
150
98
|
deploySuccess = true;
|
|
151
99
|
}
|
|
@@ -5,9 +5,9 @@ import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
|
5
5
|
import { uiBetaTag, uiLine } from '../../../lib/ui/index.js';
|
|
6
6
|
import { deprecatedProjectDevFlow } from './deprecatedFlow.js';
|
|
7
7
|
import { unifiedProjectDevFlow } from './unifiedFlow.js';
|
|
8
|
-
import { useV3Api } from '../../../lib/projects/
|
|
8
|
+
import { useV3Api } from '../../../lib/projects/platformVersion.js';
|
|
9
9
|
import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
|
|
10
|
-
import { loadProfile,
|
|
10
|
+
import { loadProfile, exitIfUsingProfiles, } from '../../../lib/projectProfiles.js';
|
|
11
11
|
import { commands } from '../../../lang/en.js';
|
|
12
12
|
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
13
13
|
const command = 'dev';
|
|
@@ -33,19 +33,37 @@ async function handler(args) {
|
|
|
33
33
|
process.exit(EXIT_CODES.ERROR);
|
|
34
34
|
}
|
|
35
35
|
validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV3);
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
uiBetaTag(commands.project.dev.logs.betaMessage);
|
|
37
|
+
if (useV3) {
|
|
38
|
+
uiLogger.log(commands.project.dev.logs.learnMoreMessageV3);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
uiLogger.log(commands.project.dev.logs.learnMoreMessageLegacy);
|
|
42
|
+
}
|
|
43
|
+
let targetProjectAccountId;
|
|
38
44
|
let profile;
|
|
45
|
+
// Using the new --projectAccount flag
|
|
46
|
+
if (projectAccount) {
|
|
47
|
+
targetProjectAccountId = getAccountId(projectAccount);
|
|
48
|
+
if (targetProjectAccountId) {
|
|
49
|
+
uiLogger.log('');
|
|
50
|
+
uiLogger.log(commands.project.dev.logs.projectAccountFlagExplanation(targetProjectAccountId));
|
|
51
|
+
}
|
|
52
|
+
// Using the legacy --account flag
|
|
53
|
+
}
|
|
54
|
+
else if (userProvidedAccount && derivedAccountId) {
|
|
55
|
+
targetProjectAccountId = derivedAccountId;
|
|
56
|
+
}
|
|
39
57
|
if (!targetProjectAccountId && useV3Api(projectConfig.platformVersion)) {
|
|
40
58
|
if (args.profile) {
|
|
41
|
-
logProfileHeader(args.profile);
|
|
42
59
|
profile = loadProfile(projectConfig, projectDir, args.profile);
|
|
43
60
|
if (!profile) {
|
|
44
61
|
uiLine();
|
|
45
62
|
process.exit(EXIT_CODES.ERROR);
|
|
46
63
|
}
|
|
47
64
|
targetProjectAccountId = profile.accountId;
|
|
48
|
-
|
|
65
|
+
uiLogger.log('');
|
|
66
|
+
uiLogger.log(commands.project.dev.logs.profileProjectAccountExplanation(targetProjectAccountId, args.profile));
|
|
49
67
|
}
|
|
50
68
|
else {
|
|
51
69
|
// A profile must be specified if this project has profiles configured
|
|
@@ -55,10 +73,12 @@ async function handler(args) {
|
|
|
55
73
|
if (!targetProjectAccountId) {
|
|
56
74
|
// The user is not using profile or account flags, so we can use the derived accountId
|
|
57
75
|
targetProjectAccountId = derivedAccountId;
|
|
76
|
+
if (useV3) {
|
|
77
|
+
uiLogger.log('');
|
|
78
|
+
uiLogger.log(commands.project.dev.logs.defaultProjectAccountExplanation(targetProjectAccountId));
|
|
79
|
+
}
|
|
58
80
|
}
|
|
59
81
|
trackCommandUsage('project-dev', {}, targetProjectAccountId);
|
|
60
|
-
uiBetaTag(commands.project.dev.logs.betaMessage);
|
|
61
|
-
uiLogger.log(commands.project.dev.logs.learnMoreLocalDevServer);
|
|
62
82
|
if (useV3Api(projectConfig.platformVersion)) {
|
|
63
83
|
const targetTestingAccountId = (testingAccount && getAccountId(testingAccount)) || undefined;
|
|
64
84
|
await unifiedProjectDevFlow({
|
|
@@ -86,13 +106,13 @@ function projectDevBuilder(yargs) {
|
|
|
86
106
|
description: commands.project.dev.options.profile,
|
|
87
107
|
hidden: true,
|
|
88
108
|
});
|
|
89
|
-
yargs.options('
|
|
109
|
+
yargs.options('testing-account', {
|
|
90
110
|
type: 'string',
|
|
91
111
|
description: commands.project.dev.options.testingAccount,
|
|
92
112
|
hidden: true,
|
|
93
|
-
implies: ['
|
|
113
|
+
implies: ['project-account'],
|
|
94
114
|
});
|
|
95
|
-
yargs.options('
|
|
115
|
+
yargs.options('project-account', {
|
|
96
116
|
type: 'string',
|
|
97
117
|
description: commands.project.dev.options.projectAccount,
|
|
98
118
|
hidden: true,
|
|
@@ -100,8 +120,8 @@ function projectDevBuilder(yargs) {
|
|
|
100
120
|
});
|
|
101
121
|
yargs.example([['$0 project dev', commands.project.dev.examples.default]]);
|
|
102
122
|
yargs.conflicts('profile', 'account');
|
|
103
|
-
yargs.conflicts('profile', '
|
|
104
|
-
yargs.conflicts('profile', '
|
|
123
|
+
yargs.conflicts('profile', 'testing-account');
|
|
124
|
+
yargs.conflicts('profile', 'project-account');
|
|
105
125
|
return yargs;
|
|
106
126
|
}
|
|
107
127
|
export const builder = makeYargsBuilder(projectDevBuilder, command, describe, {
|
|
@@ -16,13 +16,13 @@ import LocalDevProcess from '../../../lib/projects/localDev/LocalDevProcess.js';
|
|
|
16
16
|
import LocalDevWatcher from '../../../lib/projects/localDev/LocalDevWatcher.js';
|
|
17
17
|
import { handleExit, handleKeypress } from '../../../lib/process.js';
|
|
18
18
|
import { isTestAccountOrSandbox, isUnifiedAccount, } from '../../../lib/accountTypes.js';
|
|
19
|
-
import { uiLine } from '../../../lib/ui/index.js';
|
|
20
19
|
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
21
20
|
import { commands } from '../../../lang/en.js';
|
|
22
21
|
import LocalDevWebsocketServer from '../../../lib/projects/localDev/LocalDevWebsocketServer.js';
|
|
23
22
|
export async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTargetTestingAccountId, projectConfig, projectDir, }) {
|
|
24
23
|
const env = getValidEnv(getEnv(targetProjectAccountId));
|
|
25
24
|
let projectNodes;
|
|
25
|
+
let projectProfileData;
|
|
26
26
|
// Get IR
|
|
27
27
|
try {
|
|
28
28
|
const intermediateRepresentation = await translateForLocalDev({
|
|
@@ -31,6 +31,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
31
31
|
accountId: targetProjectAccountId,
|
|
32
32
|
}, { profile: args.profile });
|
|
33
33
|
projectNodes = intermediateRepresentation.intermediateNodesIndexedByUid;
|
|
34
|
+
projectProfileData = intermediateRepresentation.profileData;
|
|
34
35
|
uiLogger.debug(util.inspect(projectNodes, false, null, true));
|
|
35
36
|
}
|
|
36
37
|
catch (e) {
|
|
@@ -69,13 +70,9 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
69
70
|
!targetTestingAccountId &&
|
|
70
71
|
targetProjectAccountIsTestAccountOrSandbox) {
|
|
71
72
|
targetTestingAccountId = targetProjectAccountId;
|
|
73
|
+
uiLogger.log(commands.project.dev.logs.defaultSandboxOrDevTestTestingAccountExplanation(targetProjectAccountId));
|
|
72
74
|
}
|
|
73
75
|
else if (!targetTestingAccountId) {
|
|
74
|
-
uiLogger.log('');
|
|
75
|
-
uiLine();
|
|
76
|
-
uiLogger.log(commands.project.dev.logs.accountTypeInformation);
|
|
77
|
-
uiLogger.log(commands.project.dev.logs.learnMoreMessage);
|
|
78
|
-
uiLine();
|
|
79
76
|
uiLogger.log('');
|
|
80
77
|
const accountType = await selectAccountTypePrompt(targetProjectAccountConfig);
|
|
81
78
|
if (accountType === HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST) {
|
|
@@ -101,6 +98,9 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
101
98
|
targetTestingAccountId = targetProjectAccountId;
|
|
102
99
|
}
|
|
103
100
|
}
|
|
101
|
+
else {
|
|
102
|
+
uiLogger.log(commands.project.dev.logs.testingAccountFlagExplanation(targetTestingAccountId));
|
|
103
|
+
}
|
|
104
104
|
// Check if project exists in HubSpot
|
|
105
105
|
const { projectExists, project: uploadedProject } = await ensureProjectExists(targetProjectAccountId, projectConfig.name, {
|
|
106
106
|
allowCreate: false,
|
|
@@ -109,7 +109,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
109
109
|
let project = uploadedProject;
|
|
110
110
|
SpinniesManager.init();
|
|
111
111
|
if (projectExists && project) {
|
|
112
|
-
await compareLocalProjectToDeployed(projectConfig, targetProjectAccountId, project.deployedBuild?.buildId, projectNodes);
|
|
112
|
+
await compareLocalProjectToDeployed(projectConfig, targetProjectAccountId, project.deployedBuild?.buildId, projectNodes, args.profile);
|
|
113
113
|
}
|
|
114
114
|
else {
|
|
115
115
|
project = await createNewProjectForLocalDev(projectConfig, targetProjectAccountId, false, false);
|
|
@@ -118,6 +118,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
118
118
|
// End setup, start local dev process
|
|
119
119
|
const localDevProcess = new LocalDevProcess({
|
|
120
120
|
initialProjectNodes: projectNodes,
|
|
121
|
+
initialProjectProfileData: projectProfileData,
|
|
121
122
|
debug: args.debug,
|
|
122
123
|
profile: args.profile,
|
|
123
124
|
targetProjectAccountId,
|
|
@@ -2,14 +2,14 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { logger } from '@hubspot/local-dev-lib/logger';
|
|
3
3
|
import { getAccountConfig } from '@hubspot/local-dev-lib/config';
|
|
4
4
|
import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
|
|
5
|
-
import { useV3Api } from '../../lib/projects/
|
|
5
|
+
import { useV3Api } from '../../lib/projects/platformVersion.js';
|
|
6
6
|
import { uiBetaTag, uiCommandReference } from '../../lib/ui/index.js';
|
|
7
7
|
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
8
8
|
import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
|
|
9
9
|
import { logFeedbackMessage } from '../../lib/projects/ui.js';
|
|
10
10
|
import { handleProjectUpload } from '../../lib/projects/upload.js';
|
|
11
11
|
import { loadAndValidateProfile } from '../../lib/projectProfiles.js';
|
|
12
|
-
import { displayWarnLogs, pollProjectBuildAndDeploy, } from '../../lib/projects/
|
|
12
|
+
import { displayWarnLogs, pollProjectBuildAndDeploy, } from '../../lib/projects/pollProjectBuildAndDeploy.js';
|
|
13
13
|
import { i18n } from '../../lib/lang.js';
|
|
14
14
|
import { PROJECT_ERROR_TYPES } from '../../lib/constants.js';
|
|
15
15
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { getAccountConfig } from '@hubspot/local-dev-lib/config';
|
|
3
|
-
import { useV3Api } from '../../lib/projects/
|
|
3
|
+
import { useV3Api } from '../../lib/projects/platformVersion.js';
|
|
4
4
|
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
5
5
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
6
6
|
import { getProjectConfig, validateProjectConfig as validateProjectConfig, } from '../../lib/projects/config.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cancelStagedBuild, fetchProjectBuilds, } from '@hubspot/local-dev-lib/api/projects';
|
|
2
2
|
import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
|
|
3
|
-
import { useV3Api } from '../../lib/projects/
|
|
3
|
+
import { useV3Api } from '../../lib/projects/platformVersion.js';
|
|
4
4
|
import { uiCommandReference, uiLink, uiBetaTag } from '../../lib/ui/index.js';
|
|
5
5
|
import { i18n } from '../../lib/lang.js';
|
|
6
6
|
import { createWatcher } from '../../lib/projects/watch.js';
|
|
@@ -11,7 +11,7 @@ import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
|
11
11
|
import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
|
|
12
12
|
import { logFeedbackMessage } from '../../lib/projects/ui.js';
|
|
13
13
|
import { handleProjectUpload } from '../../lib/projects/upload.js';
|
|
14
|
-
import { pollBuildStatus, pollDeployStatus, } from '../../lib/projects/
|
|
14
|
+
import { pollBuildStatus, pollDeployStatus, } from '../../lib/projects/pollProjectBuildAndDeploy.js';
|
|
15
15
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
16
16
|
import { handleKeypress, handleExit } from '../../lib/process.js';
|
|
17
17
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
package/lang/en.d.ts
CHANGED
|
@@ -23,7 +23,8 @@ export declare const commands: {
|
|
|
23
23
|
};
|
|
24
24
|
readonly startTitle: "Welcome to HubSpot Development!";
|
|
25
25
|
readonly verboseDescribe: "A step-by-step command to get you started with a HubSpot project.";
|
|
26
|
-
readonly startDescription: "You can use the HubSpot CLI to build apps, CMS themes, and more
|
|
26
|
+
readonly startDescription: "You can use the HubSpot CLI to build apps, CMS themes, and more.\n";
|
|
27
|
+
readonly guideOverview: (accountName: string) => string;
|
|
27
28
|
readonly designManager: "To onboard with CMS, please visit the HubSpot Design Manager in your account and follow the checklist items.";
|
|
28
29
|
readonly openDesignManager: "Click here to go to the HubSpot Design Manager";
|
|
29
30
|
readonly openDesignManagerPrompt: "Open Design Manager in your browser?";
|
|
@@ -1009,10 +1010,15 @@ Profiles enable you to reference variables in your component configuration files
|
|
|
1009
1010
|
readonly logs: {
|
|
1010
1011
|
readonly betaMessage: "HubSpot projects local development";
|
|
1011
1012
|
readonly placeholderAccountSelection: "Using default account as target account (for now)";
|
|
1012
|
-
readonly learnMoreLocalDevServer: string;
|
|
1013
1013
|
readonly 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.";
|
|
1014
|
-
readonly
|
|
1015
|
-
|
|
1014
|
+
readonly learnMoreMessageV3: `Learn more about ${string} | ${string}`;
|
|
1015
|
+
readonly learnMoreMessageLegacy: string;
|
|
1016
|
+
readonly profileProjectAccountExplanation: (accountId: number, profileName: string) => string;
|
|
1017
|
+
readonly defaultProjectAccountExplanation: (accountId: number) => string;
|
|
1018
|
+
readonly projectAccountFlagExplanation: (accountId: number) => string;
|
|
1019
|
+
readonly accountFlagExplanation: (accountId: number) => string;
|
|
1020
|
+
readonly defaultSandboxOrDevTestTestingAccountExplanation: (accountId: number) => string;
|
|
1021
|
+
readonly testingAccountFlagExplanation: (accountId: number) => string;
|
|
1016
1022
|
};
|
|
1017
1023
|
readonly errors: {
|
|
1018
1024
|
readonly noProjectConfig: "No project detected. Please run this command again from a project directory.";
|
|
@@ -1022,8 +1028,8 @@ Visit our ${string} to learn more.`;
|
|
|
1022
1028
|
readonly noRunnableComponents: `No supported components were found in this project. Run ${string} to see a list of available components and add one to your project.`;
|
|
1023
1029
|
readonly accountNotCombined: `
|
|
1024
1030
|
Local 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 ${string}.`;
|
|
1025
|
-
readonly unsupportedAccountFlagLegacy: "The --
|
|
1026
|
-
readonly unsupportedAccountFlagV3: "The --account flag is is not supported supported for projects with platform versions 2025.2 and newer. Use --
|
|
1031
|
+
readonly unsupportedAccountFlagLegacy: "The --project-account and --testing-account flags are not supported for projects with platform versions earlier than 2025.2.";
|
|
1032
|
+
readonly unsupportedAccountFlagV3: "The --account flag is is not supported 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";
|
|
1027
1033
|
};
|
|
1028
1034
|
readonly examples: {
|
|
1029
1035
|
readonly default: "Start local dev for the current project";
|
|
@@ -1183,9 +1189,11 @@ ${string}`;
|
|
|
1183
1189
|
readonly success: (componentName: string, multiple?: boolean) => string;
|
|
1184
1190
|
readonly error: {
|
|
1185
1191
|
readonly failedToDownloadComponent: "Failed to download project. Please try again later.";
|
|
1192
|
+
readonly invalidComponentType: (componentType: string) => string;
|
|
1186
1193
|
readonly maxExceeded: (maxCount: number) => string;
|
|
1187
1194
|
readonly authTypeNotAllowed: (authType: string) => string;
|
|
1188
1195
|
readonly distributionNotAllowed: (dist: string) => string;
|
|
1196
|
+
readonly portalDoesNotHaveAccessToThisFeature: (accountId: number) => string;
|
|
1189
1197
|
readonly locationInProject: "This command must be run from within a project directory.";
|
|
1190
1198
|
readonly failedToFetchComponentList: "Failed to fetch the list of available features. Please try again later.";
|
|
1191
1199
|
readonly projectContainsPublicApp: "This project contains a public app. This command is currently only compatible with projects that contain private apps.";
|
|
@@ -2557,6 +2565,15 @@ export declare const lib: {
|
|
|
2557
2565
|
readonly autoInstallDeclined: "You must install your app on your target test account to proceed with local development.";
|
|
2558
2566
|
readonly autoInstallSuccess: (appName: string, targetTestAccountId: number) => string;
|
|
2559
2567
|
readonly autoInstallError: (appName: string, targetTestAccountId: number) => string;
|
|
2568
|
+
readonly fetchAppData: {
|
|
2569
|
+
readonly checking: (appName: string) => string;
|
|
2570
|
+
readonly success: (appName: string, accountId: number) => string;
|
|
2571
|
+
readonly notInstalled: (appName: string, accountId: number) => string;
|
|
2572
|
+
readonly activeInstallations: (appName: string, installCount: number) => string;
|
|
2573
|
+
readonly error: "An error occurred while checking installations for your app";
|
|
2574
|
+
};
|
|
2575
|
+
readonly distributionChanged: `Your app's distribution type has been changed from private to marketplace. Once uploaded, this change cannot be reversed. Before uploading your project, confirm that you want to ${string} change your app's distribution type. This will uninstall your app from all accounts.`;
|
|
2576
|
+
readonly authTypeChanged: `Your app's auth type has been changed from static to oauth. Once uploaded, this change cannot be reversed. Before uploading your project, confirm that you want to ${string} change your app's auth type. This will uninstall your app from all accounts.`;
|
|
2560
2577
|
};
|
|
2561
2578
|
readonly LocalDevWebsocketServer: {
|
|
2562
2579
|
readonly errors: {
|
|
@@ -2584,7 +2601,7 @@ export declare const lib: {
|
|
|
2584
2601
|
readonly checking: "Checking if your deployed build is up to date...";
|
|
2585
2602
|
readonly upToDate: "Deployed build is up to date.";
|
|
2586
2603
|
readonly notUpToDate: "Your project contains undeployed local changes.";
|
|
2587
|
-
readonly notUpToDateExplanation:
|
|
2604
|
+
readonly notUpToDateExplanation: (profile?: string) => string;
|
|
2588
2605
|
};
|
|
2589
2606
|
readonly createNewProjectForLocalDev: {
|
|
2590
2607
|
readonly projectMustExistExplanation: (projectName: string, accountId: number) => string;
|
|
@@ -2616,11 +2633,11 @@ export declare const lib: {
|
|
|
2616
2633
|
readonly notAuthedError: (parentAccountId: number | string, accountIdentifier: string) => string;
|
|
2617
2634
|
};
|
|
2618
2635
|
readonly selectAccountTypePrompt: {
|
|
2619
|
-
readonly message: "[--account] Choose the type of account to test on";
|
|
2620
|
-
readonly developerTestAccountOption: "Test on a developer test account";
|
|
2636
|
+
readonly message: "[--testing-account] Choose the type of account to test on";
|
|
2637
|
+
readonly developerTestAccountOption: "Test on a developer test account (recommended)";
|
|
2621
2638
|
readonly sandboxAccountOption: "Test on a sandbox account";
|
|
2622
2639
|
readonly sandboxAccountOptionDisabled: "Disabled - requires access to sandbox accounts";
|
|
2623
|
-
readonly productionAccountOption:
|
|
2640
|
+
readonly productionAccountOption: (accountId?: number) => string;
|
|
2624
2641
|
};
|
|
2625
2642
|
readonly confirmDefaultAccountIsTarget: {
|
|
2626
2643
|
readonly configError: `An error occurred while reading the default account from your config. Run ${string} to re-auth this account`;
|
|
@@ -2684,6 +2701,11 @@ Run ${string} to upgrade to version ${string}`;
|
|
|
2684
2701
|
readonly add: {
|
|
2685
2702
|
readonly nothingAdded: "No features added.";
|
|
2686
2703
|
};
|
|
2704
|
+
readonly updateHsMetaFilesWithAutoGeneratedFields: {
|
|
2705
|
+
readonly header: "Created the following components and features:";
|
|
2706
|
+
readonly applicationLog: (componentType: string, uid: string, name: string) => string;
|
|
2707
|
+
readonly componentLog: (componentType: string, uid: string) => string;
|
|
2708
|
+
};
|
|
2687
2709
|
readonly validateProjectConfig: {
|
|
2688
2710
|
readonly configNotFound: `Unable to locate a project configuration file. Try running again from a project directory, or run ${string} to create a new project.`;
|
|
2689
2711
|
readonly configMissingFields: "The project configuration file is missing required fields.";
|
|
@@ -3141,8 +3163,9 @@ Run ${string} to upgrade to version ${string}`;
|
|
|
3141
3163
|
};
|
|
3142
3164
|
};
|
|
3143
3165
|
readonly installAppPrompt: {
|
|
3144
|
-
readonly explanation: "Local development requires this app to be installed in the target test account";
|
|
3166
|
+
readonly explanation: "Local development requires this app to be installed in the target test account.";
|
|
3145
3167
|
readonly reinstallExplanation: "This app's required scopes have been updated since it was last installed on the target test account. To avoid issues with local development, we recommend reinstalling the app with the updated scopes.";
|
|
3168
|
+
readonly staticAuthExplanation: (projectAccountId: number, testingAccountId: number, projectName: string, appUid: string) => string;
|
|
3146
3169
|
readonly prompt: "Open HubSpot to install this app?";
|
|
3147
3170
|
readonly autoPrompt: "Install this app in your target test account?";
|
|
3148
3171
|
readonly reinstallPrompt: "Open HubSpot to reinstall this app?";
|
|
@@ -3363,7 +3386,7 @@ Run ${string} to upgrade to version ${string}`;
|
|
|
3363
3386
|
readonly componentsToBeMigrated: (components: string) => string;
|
|
3364
3387
|
readonly componentsThatWillNotBeMigrated: (components: string) => string;
|
|
3365
3388
|
readonly sourceContentsMoved: (newLocation: string) => string;
|
|
3366
|
-
readonly projectMigrationWarningTitle: "
|
|
3389
|
+
readonly projectMigrationWarningTitle: "Important: Migrating to platformVersion 2025.2 is irreversible";
|
|
3367
3390
|
readonly projectMigrationWarning: string;
|
|
3368
3391
|
readonly success: {
|
|
3369
3392
|
readonly downloadedProject: (projectName: string, projectDest: string) => string;
|
|
@@ -3378,7 +3401,7 @@ Run ${string} to upgrade to version ${string}`;
|
|
|
3378
3401
|
readonly themesAndAppsNotAllowed: "Support for migrating projects containing both themes and apps to the latest platform version is coming soon. Try again later.";
|
|
3379
3402
|
readonly multipleApps: "Multiple apps found in project, this is not allowed in 2025.2";
|
|
3380
3403
|
readonly alreadyExists: (projectName: string) => string;
|
|
3381
|
-
readonly failedToMigrateThemes: "Failed to migrate project themes. Please verify that
|
|
3404
|
+
readonly failedToMigrateThemes: "Failed to migrate project themes. Please verify that your themes are properly formatted before trying again.";
|
|
3382
3405
|
readonly failedToUpdateProjectConfig: "Failed to update project config file. Please update the platformVersion in the project config file manually.";
|
|
3383
3406
|
};
|
|
3384
3407
|
readonly unmigratableReasons: {
|