@hubspot/cli 8.10.0 → 8.12.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/account/clean.js +1 -1
- package/commands/account/list.js +1 -1
- package/commands/account/remove.js +1 -1
- package/commands/account/rename.js +1 -1
- package/commands/account/use.js +1 -1
- package/commands/api.d.ts +4 -1
- package/commands/api.js +11 -14
- package/commands/hubdb/list.d.ts +1 -1
- package/commands/mcp/setup.d.ts +2 -0
- package/commands/mcp/setup.js +29 -1
- package/commands/project/appInstallStatus.d.ts +2 -1
- package/commands/project/appInstallStatus.js +19 -17
- package/commands/project/create.js +0 -1
- package/commands/project/deploy.d.ts +2 -1
- package/commands/project/deploy.js +31 -14
- package/commands/project/dev/index.js +18 -64
- package/commands/project/info.d.ts +2 -1
- package/commands/project/info.js +8 -6
- package/commands/project/installApp.d.ts +2 -1
- package/commands/project/installApp.js +25 -26
- package/commands/project/list.js +1 -1
- package/commands/project/profile/add.d.ts +2 -1
- package/commands/project/profile/add.js +22 -1
- package/commands/project/profile/delete.d.ts +1 -1
- package/commands/project/release/create.d.ts +2 -1
- package/commands/project/release/create.js +68 -69
- package/commands/project/release/info.d.ts +2 -1
- package/commands/project/release/info.js +7 -6
- package/commands/project/release/list.d.ts +2 -1
- package/commands/project/release/list.js +14 -6
- package/commands/project/upload.d.ts +2 -1
- package/commands/project/upload.js +23 -17
- package/commands/project/validate.d.ts +1 -1
- package/commands/project.js +2 -2
- package/commands/testAccount/create.d.ts +2 -1
- package/commands/testAccount/create.js +7 -7
- package/commands/testAccount/importData.d.ts +1 -1
- package/lang/en.d.ts +32 -28
- package/lang/en.js +41 -37
- package/lib/commonOpts.js +6 -1
- package/lib/constants.d.ts +1 -0
- package/lib/constants.js +1 -0
- package/lib/jsonOutput.d.ts +109 -0
- package/lib/jsonOutput.js +94 -0
- package/lib/mcp/setup.d.ts +6 -1
- package/lib/mcp/setup.js +29 -18
- package/lib/projects/builds.d.ts +2 -0
- package/lib/projects/builds.js +22 -0
- package/lib/projects/localDev/DevSessionManager.d.ts +2 -2
- package/lib/projects/localDev/DevSessionManager.js +4 -30
- package/lib/projects/localDev/helpers/account.d.ts +0 -7
- package/lib/projects/localDev/helpers/account.js +1 -80
- package/lib/projects/release.d.ts +4 -0
- package/lib/projects/release.js +90 -0
- package/lib/projects/upload.d.ts +1 -1
- package/lib/projects/upload.js +4 -8
- package/lib/yargs/makeWrappedYargsHandler.d.ts +5 -1
- package/lib/yargs/makeWrappedYargsHandler.js +123 -65
- package/mcp-server/Tool.d.ts +8 -3
- package/mcp-server/Tool.js +58 -32
- package/mcp-server/server.js +10 -6
- package/mcp-server/tools/cms/HsCreateFunctionTool.d.ts +2 -2
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +10 -17
- package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +2 -2
- package/mcp-server/tools/cms/HsCreateModuleTool.js +12 -18
- package/mcp-server/tools/cms/HsCreateTemplateTool.d.ts +2 -2
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +8 -10
- package/mcp-server/tools/cms/HsFunctionLogsTool.d.ts +2 -2
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +9 -9
- package/mcp-server/tools/cms/HsListFunctionsTool.d.ts +2 -2
- package/mcp-server/tools/cms/HsListFunctionsTool.js +7 -7
- package/mcp-server/tools/cms/HsListTool.d.ts +2 -2
- package/mcp-server/tools/cms/HsListTool.js +6 -10
- package/mcp-server/tools/index.js +2 -0
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +2 -2
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +8 -9
- package/mcp-server/tools/project/AuthAccountTool.d.ts +18 -0
- package/mcp-server/tools/project/AuthAccountTool.js +78 -0
- package/mcp-server/tools/project/CreateProjectTool.d.ts +2 -2
- package/mcp-server/tools/project/CreateProjectTool.js +13 -12
- package/mcp-server/tools/project/CreateTestAccountTool.d.ts +2 -2
- package/mcp-server/tools/project/CreateTestAccountTool.js +14 -15
- package/mcp-server/tools/project/DeployProjectTool.d.ts +2 -2
- package/mcp-server/tools/project/DeployProjectTool.js +10 -10
- package/mcp-server/tools/project/DocFetchTool.js +1 -1
- package/mcp-server/tools/project/DocsSearchTool.js +9 -3
- package/mcp-server/tools/project/FindProjectsTool.js +1 -1
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +9 -4
- package/mcp-server/tools/project/GetApplicationInfoTool.js +9 -4
- package/mcp-server/tools/project/GetBuildLogsTool.js +9 -3
- package/mcp-server/tools/project/GetBuildStatusTool.js +9 -3
- package/mcp-server/tools/project/GetConfigValuesTool.js +9 -3
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +1 -1
- package/mcp-server/tools/project/UploadProjectTools.d.ts +2 -2
- package/mcp-server/tools/project/UploadProjectTools.js +9 -8
- package/mcp-server/tools/project/ValidateProjectTool.d.ts +2 -2
- package/mcp-server/tools/project/ValidateProjectTool.js +5 -4
- package/mcp-server/utils/command.d.ts +25 -2
- package/mcp-server/utils/command.js +67 -17
- package/mcp-server/utils/logger.d.ts +3 -0
- package/mcp-server/utils/logger.js +30 -0
- package/mcp-server/utils/toolUsageTracking.js +8 -1
- package/package.json +10 -8
- package/types/Yargs.d.ts +3 -1
- package/commands/project/dev/deprecatedFlow.d.ts +0 -11
- package/commands/project/dev/deprecatedFlow.js +0 -180
- package/lib/projects/localDev/DevServerManager_DEPRECATED.d.ts +0 -43
- package/lib/projects/localDev/DevServerManager_DEPRECATED.js +0 -128
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.d.ts +0 -64
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +0 -394
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getConfigAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
3
3
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
4
|
+
import { InstallAppSchema, } from '../../lib/jsonOutput.js';
|
|
4
5
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
5
6
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
6
7
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
@@ -13,7 +14,7 @@ const command = 'install-app';
|
|
|
13
14
|
const describe = commands.project.installApp.describe;
|
|
14
15
|
const verboseDescribe = commands.project.installApp.verboseDescribe;
|
|
15
16
|
async function handler(args) {
|
|
16
|
-
const { derivedAccountId, formatOutputAsJson, force, profile: profileOption, useEnv: useEnvOption, exit, } = args;
|
|
17
|
+
const { derivedAccountId, formatOutputAsJson, force, profile: profileOption, useEnv: useEnvOption, exit, addJsonOutput, } = args;
|
|
17
18
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
18
19
|
if (!projectConfig || !projectDir) {
|
|
19
20
|
uiLogger.error(commands.project.installApp.errors.noProjectConfig);
|
|
@@ -60,18 +61,16 @@ async function handler(args) {
|
|
|
60
61
|
const needsReinstall = !isInstalledWithScopeGroups && previouslyAuthorizedScopeGroups.length > 0;
|
|
61
62
|
const installationState = getAppInstallationState(isInstalledWithScopeGroups, previouslyAuthorizedScopeGroups);
|
|
62
63
|
if (isInstalledWithScopeGroups) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
64
|
+
addJsonOutput({
|
|
65
|
+
appId,
|
|
66
|
+
appUid: appNode.uid,
|
|
67
|
+
accountId: installAccountId,
|
|
68
|
+
projectId,
|
|
69
|
+
installationState,
|
|
70
|
+
installed: true,
|
|
71
|
+
reinstalled: false,
|
|
72
|
+
});
|
|
73
|
+
if (!formatOutputAsJson) {
|
|
75
74
|
uiLogger.success(commands.project.installApp.alreadyInstalled(appNode.config.name, installAccountId));
|
|
76
75
|
}
|
|
77
76
|
return exit(EXIT_CODES.SUCCESS);
|
|
@@ -117,18 +116,16 @@ async function handler(args) {
|
|
|
117
116
|
if (!installed) {
|
|
118
117
|
return exit(EXIT_CODES.ERROR);
|
|
119
118
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
119
|
+
addJsonOutput({
|
|
120
|
+
appId,
|
|
121
|
+
appUid: appNode.uid,
|
|
122
|
+
accountId: installAccountId,
|
|
123
|
+
projectId,
|
|
124
|
+
installationState: APP_INSTALLATION_STATES.INSTALLED,
|
|
125
|
+
installed: true,
|
|
126
|
+
reinstalled: needsReinstall,
|
|
127
|
+
});
|
|
128
|
+
if (!formatOutputAsJson) {
|
|
132
129
|
uiLogger.success(commands.project.installApp.success(appNode.config.name, installAccountId));
|
|
133
130
|
}
|
|
134
131
|
return exit(EXIT_CODES.SUCCESS);
|
|
@@ -175,7 +172,9 @@ const builder = makeYargsBuilder(projectInstallAppBuilder, command, verboseDescr
|
|
|
175
172
|
const projectInstallAppCommand = {
|
|
176
173
|
command,
|
|
177
174
|
describe,
|
|
178
|
-
handler: makeWrappedYargsHandler('project-install-app', handler
|
|
175
|
+
handler: makeWrappedYargsHandler('project-install-app', handler, {
|
|
176
|
+
jsonOutputSchema: InstallAppSchema,
|
|
177
|
+
}),
|
|
179
178
|
builder,
|
|
180
179
|
};
|
|
181
180
|
export default projectInstallAppCommand;
|
package/commands/project/list.js
CHANGED
|
@@ -57,7 +57,7 @@ const builder = makeYargsBuilder(projectListBuilder, command, describe, {
|
|
|
57
57
|
const projectListCommand = {
|
|
58
58
|
command,
|
|
59
59
|
describe,
|
|
60
|
-
handler: makeWrappedYargsHandler('
|
|
60
|
+
handler: makeWrappedYargsHandler('project-list', handler),
|
|
61
61
|
builder,
|
|
62
62
|
};
|
|
63
63
|
export default projectListCommand;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { YargsCommandModule, CommonArgs } from '../../../types/Yargs.js';
|
|
2
|
-
type ProjectProfileAddArgs = CommonArgs & {
|
|
2
|
+
export type ProjectProfileAddArgs = CommonArgs & {
|
|
3
3
|
name?: string;
|
|
4
4
|
targetAccount?: number;
|
|
5
|
+
copyFrom?: string;
|
|
5
6
|
};
|
|
6
7
|
declare const projectProfileAddCommand: YargsCommandModule<unknown, ProjectProfileAddArgs>;
|
|
7
8
|
export default projectProfileAddCommand;
|
|
@@ -157,7 +157,20 @@ async function handler(args) {
|
|
|
157
157
|
accountId: targetAccountId,
|
|
158
158
|
variables: {},
|
|
159
159
|
};
|
|
160
|
-
|
|
160
|
+
let profileToCopyVariablesFrom;
|
|
161
|
+
if (args.copyFrom) {
|
|
162
|
+
if (existingProfiles.includes(args.copyFrom)) {
|
|
163
|
+
profileToCopyVariablesFrom = args.copyFrom;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
uiLogger.error(commands.project.profile.add.errors.copyFromProfileNotFound(args.copyFrom));
|
|
167
|
+
return exit(EXIT_CODES.ERROR);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
profileToCopyVariablesFrom =
|
|
172
|
+
await selectProfileToCopyVariablesFrom(existingProfiles);
|
|
173
|
+
}
|
|
161
174
|
if (profileToCopyVariablesFrom) {
|
|
162
175
|
try {
|
|
163
176
|
const profileToCopyFileContent = loadHsProfileFile(projectSourceDir, profileToCopyVariablesFrom);
|
|
@@ -190,8 +203,16 @@ function projectProfileAddBuilder(yargs) {
|
|
|
190
203
|
describe: commands.project.profile.add.options.targetAccount,
|
|
191
204
|
type: 'number',
|
|
192
205
|
});
|
|
206
|
+
yargs.option('copy-from', {
|
|
207
|
+
describe: commands.project.profile.add.options.copyFrom,
|
|
208
|
+
type: 'string',
|
|
209
|
+
});
|
|
193
210
|
yargs.example([
|
|
194
211
|
['$0 project profile add qa', commands.project.profile.add.example],
|
|
212
|
+
[
|
|
213
|
+
'$0 project profile add qa --target-account 123 --copy-from staging',
|
|
214
|
+
commands.project.profile.add.exampleCopyFrom,
|
|
215
|
+
],
|
|
195
216
|
]);
|
|
196
217
|
return yargs;
|
|
197
218
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { YargsCommandModule, CommonArgs } from '../../../types/Yargs.js';
|
|
2
|
-
type ProjectProfileDeleteArgs = CommonArgs & {
|
|
2
|
+
export type ProjectProfileDeleteArgs = CommonArgs & {
|
|
3
3
|
name?: string;
|
|
4
4
|
};
|
|
5
5
|
declare const projectProfileDeleteCommand: YargsCommandModule<unknown, ProjectProfileDeleteArgs>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../../types/Yargs.js';
|
|
2
|
-
|
|
2
|
+
import { ReleaseJsonOutput } from '../../../lib/jsonOutput.js';
|
|
3
|
+
export type ProjectReleaseCreateArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ReleaseJsonOutput> & {
|
|
3
4
|
build?: number;
|
|
4
5
|
force: boolean;
|
|
5
6
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { handleProjectUpload } from '../../../lib/projects/upload.js';
|
|
2
|
+
import { pollProjectBuildAndDeploy } from '../../../lib/projects/pollProjectBuildAndDeploy.js';
|
|
3
|
+
import { resolveBuildId, validateBuildForRelease, executeRelease, } from '../../../lib/projects/release.js';
|
|
3
4
|
import { logError, ApiErrorContext } from '../../../lib/errorHandlers/index.js';
|
|
5
|
+
import { isPromptExitError } from '../../../lib/errors/PromptExitError.js';
|
|
4
6
|
import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/config.js';
|
|
5
7
|
import { confirmPrompt } from '../../../lib/prompts/promptUtils.js';
|
|
6
8
|
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
@@ -8,64 +10,23 @@ import { uiLogger } from '../../../lib/ui/logger.js';
|
|
|
8
10
|
import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
|
|
9
11
|
import { commands } from '../../../lang/en.js';
|
|
10
12
|
import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
|
|
11
|
-
import {
|
|
13
|
+
import { ReleaseSchema, mapReleaseToJsonOutput, } from '../../../lib/jsonOutput.js';
|
|
12
14
|
const command = 'create';
|
|
13
15
|
// const describe = commands.project.release.create.describe;
|
|
14
16
|
const describe = undefined;
|
|
15
17
|
// const verboseDescribe = commands.project.release.create.verboseDescribe;
|
|
16
18
|
const verboseDescribe = undefined;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return buildOption;
|
|
21
|
-
}
|
|
22
|
-
if (!deployedBuildId) {
|
|
23
|
-
throw new Error(commands.project.release.create.errors.noDeployedBuild);
|
|
24
|
-
}
|
|
25
|
-
return deployedBuildId;
|
|
26
|
-
}
|
|
27
|
-
async function validateBuild(accountId, projectName, buildId) {
|
|
28
|
-
try {
|
|
29
|
-
await getBuildStatus(accountId, projectName, buildId);
|
|
30
|
-
}
|
|
31
|
-
catch (e) {
|
|
32
|
-
if (isHubSpotHttpError(e) && e.status === 404) {
|
|
33
|
-
uiLogger.error(commands.project.release.create.errors.buildNotFound(buildId, projectName));
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
logError(e, new ApiErrorContext({
|
|
37
|
-
accountId,
|
|
38
|
-
request: 'project release create',
|
|
39
|
-
}));
|
|
40
|
-
}
|
|
41
|
-
throw e;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
async function executeRelease(accountId, projectName, buildId, formatOutputAsJson) {
|
|
45
|
-
try {
|
|
46
|
-
const { data: release } = await createRelease(accountId, projectName, buildId);
|
|
47
|
-
if (formatOutputAsJson) {
|
|
48
|
-
uiLogger.json(release);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
uiLogger.success(commands.project.release.create.success(release.releaseTag, release.buildId));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
if (isHubSpotHttpError(e) && e.status === 422) {
|
|
56
|
-
uiLogger.error(commands.project.release.create.errors.buildNotDeployed(buildId));
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
logError(e, new ApiErrorContext({
|
|
60
|
-
accountId,
|
|
61
|
-
request: 'project release create',
|
|
62
|
-
}));
|
|
63
|
-
}
|
|
64
|
-
throw e;
|
|
19
|
+
function logUploadError(error, accountId) {
|
|
20
|
+
if (!error) {
|
|
21
|
+
return;
|
|
65
22
|
}
|
|
23
|
+
logError(error, new ApiErrorContext({
|
|
24
|
+
accountId,
|
|
25
|
+
request: 'project release create',
|
|
26
|
+
}));
|
|
66
27
|
}
|
|
67
28
|
async function handler(args) {
|
|
68
|
-
const { exit, derivedAccountId, build: buildOption, json: formatOutputAsJson, force, } = args;
|
|
29
|
+
const { exit, derivedAccountId, build: buildOption, json: formatOutputAsJson, force, addJsonOutput, } = args;
|
|
69
30
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
70
31
|
try {
|
|
71
32
|
validateProjectConfig(projectConfig, projectDir);
|
|
@@ -74,34 +35,66 @@ async function handler(args) {
|
|
|
74
35
|
logError(error);
|
|
75
36
|
return exit(EXIT_CODES.ERROR);
|
|
76
37
|
}
|
|
38
|
+
if (!projectConfig || !projectDir) {
|
|
39
|
+
return exit(EXIT_CODES.ERROR);
|
|
40
|
+
}
|
|
77
41
|
const projectName = projectConfig.name;
|
|
78
42
|
let buildId;
|
|
79
43
|
try {
|
|
80
|
-
buildId = await resolveBuildId(derivedAccountId, projectName, buildOption);
|
|
44
|
+
buildId = await resolveBuildId(derivedAccountId, projectName, buildOption, force);
|
|
81
45
|
}
|
|
82
46
|
catch (e) {
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
else if (!(e instanceof Error) || !e.message) {
|
|
87
|
-
logError(e, new ApiErrorContext({
|
|
88
|
-
accountId: derivedAccountId,
|
|
89
|
-
request: 'project release create',
|
|
90
|
-
}));
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
uiLogger.error(e.message);
|
|
47
|
+
if (isPromptExitError(e)) {
|
|
48
|
+
return exit(e.exitCode);
|
|
94
49
|
}
|
|
50
|
+
logError(e, new ApiErrorContext({
|
|
51
|
+
accountId: derivedAccountId,
|
|
52
|
+
request: 'project release create',
|
|
53
|
+
}));
|
|
54
|
+
return exit(EXIT_CODES.ERROR);
|
|
55
|
+
}
|
|
56
|
+
if (buildId === null) {
|
|
95
57
|
return exit(EXIT_CODES.ERROR);
|
|
96
58
|
}
|
|
97
|
-
if (
|
|
59
|
+
if (!buildId && !force) {
|
|
60
|
+
let shouldUpload;
|
|
98
61
|
try {
|
|
99
|
-
await
|
|
62
|
+
shouldUpload = await confirmPrompt(commands.project.release.create.uploadPrompt(projectName));
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
if (isPromptExitError(e)) {
|
|
66
|
+
return exit(e.exitCode);
|
|
67
|
+
}
|
|
68
|
+
throw e;
|
|
69
|
+
}
|
|
70
|
+
if (!shouldUpload) {
|
|
71
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (!buildId) {
|
|
75
|
+
const { result: pollResult, uploadError, projectNotFound, } = await handleProjectUpload({
|
|
76
|
+
accountId: derivedAccountId,
|
|
77
|
+
projectConfig,
|
|
78
|
+
projectDir,
|
|
79
|
+
sendIR: true,
|
|
80
|
+
callbackFunc: (...args) => pollProjectBuildAndDeploy(...args, { skipDeploy: true }),
|
|
81
|
+
});
|
|
82
|
+
if (projectNotFound || !pollResult || !pollResult.succeeded) {
|
|
83
|
+
logUploadError(uploadError, derivedAccountId);
|
|
84
|
+
return exit(EXIT_CODES.ERROR);
|
|
100
85
|
}
|
|
101
|
-
|
|
86
|
+
buildId = pollResult.buildId;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const supportsReleases = await validateBuildForRelease(derivedAccountId, projectName, buildId);
|
|
90
|
+
if (!supportsReleases) {
|
|
91
|
+
uiLogger.error(commands.project.release.create.errors.incompatibleBuildVersion);
|
|
102
92
|
return exit(EXIT_CODES.ERROR);
|
|
103
93
|
}
|
|
104
94
|
}
|
|
95
|
+
catch {
|
|
96
|
+
return exit(EXIT_CODES.ERROR);
|
|
97
|
+
}
|
|
105
98
|
if (!formatOutputAsJson && !force) {
|
|
106
99
|
const confirmed = await confirmPrompt(commands.project.release.create.confirmPrompt(projectName, buildId));
|
|
107
100
|
if (!confirmed) {
|
|
@@ -110,7 +103,11 @@ async function handler(args) {
|
|
|
110
103
|
}
|
|
111
104
|
}
|
|
112
105
|
try {
|
|
113
|
-
await executeRelease(derivedAccountId, projectName, buildId
|
|
106
|
+
const release = await executeRelease(derivedAccountId, projectName, buildId);
|
|
107
|
+
addJsonOutput(mapReleaseToJsonOutput(release));
|
|
108
|
+
if (!formatOutputAsJson) {
|
|
109
|
+
uiLogger.success(commands.project.release.create.success(release.releaseTag, release.buildId));
|
|
110
|
+
}
|
|
114
111
|
}
|
|
115
112
|
catch {
|
|
116
113
|
return exit(EXIT_CODES.ERROR);
|
|
@@ -154,6 +151,8 @@ const projectReleaseCreateCommand = {
|
|
|
154
151
|
command,
|
|
155
152
|
describe,
|
|
156
153
|
builder,
|
|
157
|
-
handler: makeWrappedYargsHandler('project-release-create', handler
|
|
154
|
+
handler: makeWrappedYargsHandler('project-release-create', handler, {
|
|
155
|
+
jsonOutputSchema: ReleaseSchema,
|
|
156
|
+
}),
|
|
158
157
|
};
|
|
159
158
|
export default projectReleaseCreateCommand;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../../types/Yargs.js';
|
|
2
|
-
|
|
2
|
+
import { ReleaseJsonOutput } from '../../../lib/jsonOutput.js';
|
|
3
|
+
export type ProjectReleaseInfoArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ReleaseJsonOutput> & {
|
|
3
4
|
tag?: string;
|
|
4
5
|
};
|
|
5
6
|
declare const projectReleaseInfoCommand: YargsCommandModule<unknown, ProjectReleaseInfoArgs>;
|
|
@@ -12,6 +12,7 @@ import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHand
|
|
|
12
12
|
import { isPromptExitError } from '../../../lib/errors/PromptExitError.js';
|
|
13
13
|
import { mapToUserFacingType } from '@hubspot/project-parsing-lib/transform';
|
|
14
14
|
import { AUTO_GENERATED_COMPONENT_TYPES } from '@hubspot/project-parsing-lib/constants';
|
|
15
|
+
import { ReleaseSchema, mapReleaseToJsonOutput, } from '../../../lib/jsonOutput.js';
|
|
15
16
|
const command = 'info';
|
|
16
17
|
// const describe = commands.project.release.info.describe;
|
|
17
18
|
const describe = undefined;
|
|
@@ -36,7 +37,7 @@ async function selectReleasePrompt(accountId, projectName) {
|
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
async function handler(args) {
|
|
39
|
-
const { derivedAccountId, tag: rawTag, json: formatOutputAsJson, exit, } = args;
|
|
40
|
+
const { derivedAccountId, tag: rawTag, json: formatOutputAsJson, exit, addJsonOutput, } = args;
|
|
40
41
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
41
42
|
try {
|
|
42
43
|
validateProjectConfig(projectConfig, projectDir);
|
|
@@ -69,10 +70,8 @@ async function handler(args) {
|
|
|
69
70
|
}
|
|
70
71
|
try {
|
|
71
72
|
const { data: release } = await getReleaseInfo(derivedAccountId, projectName, tag);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
73
|
+
addJsonOutput(mapReleaseToJsonOutput(release));
|
|
74
|
+
if (!formatOutputAsJson) {
|
|
76
75
|
uiLogger.log(commands.project.release.info.releaseDetails(release.releaseTag, projectName));
|
|
77
76
|
renderTable(['Release', 'Build', 'Created'], [
|
|
78
77
|
[
|
|
@@ -142,6 +141,8 @@ const projectReleaseInfoCommand = {
|
|
|
142
141
|
command,
|
|
143
142
|
describe,
|
|
144
143
|
builder,
|
|
145
|
-
handler: makeWrappedYargsHandler('project-release-info', handler
|
|
144
|
+
handler: makeWrappedYargsHandler('project-release-info', handler, {
|
|
145
|
+
jsonOutputSchema: ReleaseSchema,
|
|
146
|
+
}),
|
|
146
147
|
};
|
|
147
148
|
export default projectReleaseInfoCommand;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../../types/Yargs.js';
|
|
2
|
-
|
|
2
|
+
import { ReleaseListJsonOutput } from '../../../lib/jsonOutput.js';
|
|
3
|
+
export type ProjectReleaseListArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ReleaseListJsonOutput> & {
|
|
3
4
|
limit?: number;
|
|
4
5
|
};
|
|
5
6
|
declare const projectReleaseListCommand: YargsCommandModule<unknown, ProjectReleaseListArgs>;
|
|
@@ -10,6 +10,7 @@ import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
|
|
|
10
10
|
import { commands } from '../../../lang/en.js';
|
|
11
11
|
import { renderTable } from '../../../ui/render.js';
|
|
12
12
|
import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
|
|
13
|
+
import { ReleaseListSchema, mapReleaseToJsonOutput, } from '../../../lib/jsonOutput.js';
|
|
13
14
|
const command = 'list';
|
|
14
15
|
// const describe = commands.project.release.list.describe;
|
|
15
16
|
const describe = undefined;
|
|
@@ -41,14 +42,14 @@ async function fetchAndDisplayReleases(accountId, projectName, options) {
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
async function handler(args) {
|
|
44
|
-
const { derivedAccountId, limit, json: formatOutputAsJson } = args;
|
|
45
|
+
const { derivedAccountId, limit, json: formatOutputAsJson, exit, addJsonOutput, } = args;
|
|
45
46
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
46
47
|
try {
|
|
47
48
|
validateProjectConfig(projectConfig, projectDir);
|
|
48
49
|
}
|
|
49
50
|
catch (error) {
|
|
50
51
|
logError(error);
|
|
51
|
-
|
|
52
|
+
return exit(EXIT_CODES.ERROR);
|
|
52
53
|
}
|
|
53
54
|
const projectName = projectConfig.name;
|
|
54
55
|
try {
|
|
@@ -56,7 +57,12 @@ async function handler(args) {
|
|
|
56
57
|
const { data } = await listReleases(derivedAccountId, projectName, {
|
|
57
58
|
limit,
|
|
58
59
|
});
|
|
59
|
-
|
|
60
|
+
addJsonOutput({
|
|
61
|
+
results: data.results.map(mapReleaseToJsonOutput),
|
|
62
|
+
paging: data.paging
|
|
63
|
+
? { next: { after: data.paging.next.after } }
|
|
64
|
+
: undefined,
|
|
65
|
+
});
|
|
60
66
|
}
|
|
61
67
|
else {
|
|
62
68
|
await fetchAndDisplayReleases(derivedAccountId, projectName, { limit });
|
|
@@ -75,9 +81,9 @@ async function handler(args) {
|
|
|
75
81
|
request: 'project release list',
|
|
76
82
|
}));
|
|
77
83
|
}
|
|
78
|
-
|
|
84
|
+
return exit(EXIT_CODES.ERROR);
|
|
79
85
|
}
|
|
80
|
-
|
|
86
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
81
87
|
}
|
|
82
88
|
function projectReleaseListBuilder(yargs) {
|
|
83
89
|
yargs.options({
|
|
@@ -106,6 +112,8 @@ const projectReleaseListCommand = {
|
|
|
106
112
|
command,
|
|
107
113
|
describe,
|
|
108
114
|
builder,
|
|
109
|
-
handler: makeWrappedYargsHandler('project-release-list', handler
|
|
115
|
+
handler: makeWrappedYargsHandler('project-release-list', handler, {
|
|
116
|
+
jsonOutputSchema: ReleaseListSchema,
|
|
117
|
+
}),
|
|
110
118
|
};
|
|
111
119
|
export default projectReleaseListCommand;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CommonArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
|
|
2
|
+
import { UploadJsonOutput } from '../../lib/jsonOutput.js';
|
|
3
|
+
export type ProjectUploadArgs = CommonArgs & JSONOutputArgs<UploadJsonOutput> & {
|
|
3
4
|
force: boolean;
|
|
4
5
|
forceCreate: boolean;
|
|
5
6
|
message: string;
|
|
@@ -2,7 +2,7 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
3
3
|
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
4
4
|
import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
|
|
5
|
-
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
5
|
+
import { isLegacyProject, meetsMinimumPlatformVersion, } from '@hubspot/project-parsing-lib/projects';
|
|
6
6
|
import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
|
|
7
7
|
import { logFeedbackMessage } from '../../lib/projects/ui.js';
|
|
8
8
|
import { handleProjectUpload } from '../../lib/projects/upload.js';
|
|
@@ -14,9 +14,11 @@ import { PROJECT_ERROR_TYPES } from '../../lib/constants.js';
|
|
|
14
14
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
15
15
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
16
16
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
17
|
+
import { UploadSchema, } from '../../lib/jsonOutput.js';
|
|
17
18
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
18
19
|
import { projectProfilePrompt } from '../../lib/prompts/projectProfilePrompt.js';
|
|
19
20
|
import { showMcpPromotionNudge } from '../../lib/mcp/promotion.js';
|
|
21
|
+
import { PLATFORM_VERSIONS } from '@hubspot/project-parsing-lib/constants';
|
|
20
22
|
const command = 'upload';
|
|
21
23
|
const describe = commands.project.upload.describe;
|
|
22
24
|
async function handlePreview(accountId, projectId, buildId, targetPortalId) {
|
|
@@ -34,8 +36,7 @@ async function handlePreview(accountId, projectId, buildId, targetPortalId) {
|
|
|
34
36
|
};
|
|
35
37
|
}
|
|
36
38
|
async function handler(args) {
|
|
37
|
-
const { force = false, forceCreate = false, message, derivedAccountId, skipValidation, skipNpmAudit, skipAutoDeploy, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, preview, target: targetPortalId, exit, addUsageMetadata, } = args;
|
|
38
|
-
const jsonOutput = {};
|
|
39
|
+
const { force = false, forceCreate = false, message, derivedAccountId, skipValidation, skipNpmAudit, skipAutoDeploy, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, preview, target: targetPortalId, exit, addUsageMetadata, addJsonOutput, } = args;
|
|
39
40
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
40
41
|
try {
|
|
41
42
|
validateProjectConfig(projectConfig, projectDir);
|
|
@@ -113,27 +114,33 @@ async function handler(args) {
|
|
|
113
114
|
(!result.buildResult.isAutoDeployEnabled || preview || skipAutoDeploy)) {
|
|
114
115
|
uiLogger.log(chalk.bold(commands.project.upload.logs.buildSucceeded(result.buildId)));
|
|
115
116
|
if (!preview) {
|
|
116
|
-
|
|
117
|
+
if (meetsMinimumPlatformVersion(result.buildResult.platformVersion, PLATFORM_VERSIONS.v2026_09_BETA)) {
|
|
118
|
+
const releaseCommand = `hs project release create --build=${result.buildId}`;
|
|
119
|
+
uiLogger.log(commands.project.upload.logs.releaseManagementRequired(releaseCommand));
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const deployCommand = `hs project deploy --build=${result.buildId}`;
|
|
123
|
+
uiLogger.log(skipAutoDeploy
|
|
124
|
+
? commands.project.upload.logs.autoDeploySkipped(deployCommand)
|
|
125
|
+
: commands.project.upload.logs.autoDeployDisabled(deployCommand));
|
|
126
|
+
}
|
|
117
127
|
logFeedbackMessage(result.buildId);
|
|
118
128
|
}
|
|
119
129
|
await displayWarnLogs(targetAccountId, projectConfig.name, result.buildId);
|
|
120
130
|
}
|
|
121
131
|
if (result && result.succeeded && preview && targetPortalId) {
|
|
122
132
|
const previewJson = await handlePreview(targetAccountId, projectId, result.buildId, targetPortalId);
|
|
123
|
-
if (previewJson
|
|
124
|
-
|
|
133
|
+
if (previewJson) {
|
|
134
|
+
addJsonOutput({ preview: previewJson });
|
|
125
135
|
}
|
|
126
136
|
}
|
|
127
|
-
if (result
|
|
128
|
-
|
|
137
|
+
if (result) {
|
|
138
|
+
addJsonOutput({ buildId: result.buildId });
|
|
129
139
|
if (result.deployResult) {
|
|
130
|
-
|
|
140
|
+
addJsonOutput({ deployId: result.deployResult.deployId });
|
|
131
141
|
}
|
|
132
142
|
}
|
|
133
143
|
if (result && !result.succeeded) {
|
|
134
|
-
if (formatOutputAsJson) {
|
|
135
|
-
uiLogger.json(jsonOutput);
|
|
136
|
-
}
|
|
137
144
|
return exit(EXIT_CODES.ERROR);
|
|
138
145
|
}
|
|
139
146
|
if (!result && !uploadError) {
|
|
@@ -147,10 +154,7 @@ async function handler(args) {
|
|
|
147
154
|
}));
|
|
148
155
|
return exit(EXIT_CODES.ERROR);
|
|
149
156
|
}
|
|
150
|
-
if (formatOutputAsJson) {
|
|
151
|
-
uiLogger.json(jsonOutput);
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
157
|
+
if (!formatOutputAsJson) {
|
|
154
158
|
await showMcpPromotionNudge(args._.join(' '));
|
|
155
159
|
}
|
|
156
160
|
return exit(EXIT_CODES.SUCCESS);
|
|
@@ -242,7 +246,9 @@ const builder = makeYargsBuilder(projectUploadBuilder, command, describe, {
|
|
|
242
246
|
const projectUploadCommand = {
|
|
243
247
|
command,
|
|
244
248
|
describe,
|
|
245
|
-
handler: makeWrappedYargsHandler('project-upload', handler
|
|
249
|
+
handler: makeWrappedYargsHandler('project-upload', handler, {
|
|
250
|
+
jsonOutputSchema: UploadSchema,
|
|
251
|
+
}),
|
|
246
252
|
builder,
|
|
247
253
|
};
|
|
248
254
|
export default projectUploadCommand;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommonArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
type ProjectValidateArgs = CommonArgs & {
|
|
2
|
+
export type ProjectValidateArgs = CommonArgs & {
|
|
3
3
|
profile?: string;
|
|
4
4
|
};
|
|
5
5
|
declare const projectValidateCommand: YargsCommandModule<unknown, ProjectValidateArgs>;
|
package/commands/project.js
CHANGED
|
@@ -24,7 +24,7 @@ import appInstallStatus from './project/appInstallStatus.js';
|
|
|
24
24
|
import installApp from './project/installApp.js';
|
|
25
25
|
import { makeYargsBuilder } from '../lib/yargsUtils.js';
|
|
26
26
|
import { getProjectConfig } from '../lib/projects/config.js';
|
|
27
|
-
import {
|
|
27
|
+
import { isKnownPlatformVersion, LATEST_SUPPORTED_PLATFORM_VERSION, } from '@hubspot/project-parsing-lib/projects';
|
|
28
28
|
import { uiLogger } from '../lib/ui/logger.js';
|
|
29
29
|
import { debugError } from '../lib/errorHandlers/index.js';
|
|
30
30
|
const command = ['project', 'projects'];
|
|
@@ -37,7 +37,7 @@ async function validatePlatformVersion() {
|
|
|
37
37
|
// Only warn if a platform version is explicitly set but not supported
|
|
38
38
|
// Don't warn if the platform version is missing/undefined
|
|
39
39
|
if (projectConfig?.platformVersion &&
|
|
40
|
-
!
|
|
40
|
+
!isKnownPlatformVersion(projectConfig.platformVersion)) {
|
|
41
41
|
uiLogger.warn(lib.projects.platformVersion.unsupported(pkg.version, LATEST_SUPPORTED_PLATFORM_VERSION, projectConfig.platformVersion));
|
|
42
42
|
uiLogger.log('');
|
|
43
43
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AccountLevel } from '@hubspot/local-dev-lib/types/developerTestAccounts.js';
|
|
2
2
|
import { CommonArgs, ConfigArgs, AccountArgs, TestingArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
3
|
-
|
|
3
|
+
import { CreateTestAccountJsonOutput } from '../../lib/jsonOutput.js';
|
|
4
|
+
type CreateTestAccountArgs = CommonArgs & AccountArgs & ConfigArgs & TestingArgs & EnvironmentArgs & JSONOutputArgs<CreateTestAccountJsonOutput> & {
|
|
4
5
|
configPath?: string;
|
|
5
6
|
name?: string;
|
|
6
7
|
description?: string;
|
|
@@ -4,6 +4,7 @@ import { getValidEnv } from '@hubspot/local-dev-lib/environment';
|
|
|
4
4
|
import { getConfigAccountEnvironment } from '@hubspot/local-dev-lib/config';
|
|
5
5
|
import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
6
6
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
7
|
+
import { CreateTestAccountSchema, } from '../../lib/jsonOutput.js';
|
|
7
8
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
8
9
|
import { promptUser, listPrompt } from '../../lib/prompts/promptUtils.js';
|
|
9
10
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
@@ -88,7 +89,7 @@ async function buildTestAccountConfig(args) {
|
|
|
88
89
|
});
|
|
89
90
|
}
|
|
90
91
|
async function handler(args) {
|
|
91
|
-
const { derivedAccountId, formatOutputAsJson, exit } = args;
|
|
92
|
+
const { derivedAccountId, formatOutputAsJson, exit, addJsonOutput } = args;
|
|
92
93
|
const env = getValidEnv(getConfigAccountEnvironment(derivedAccountId));
|
|
93
94
|
let testAccountConfig;
|
|
94
95
|
try {
|
|
@@ -121,11 +122,8 @@ async function handler(args) {
|
|
|
121
122
|
SpinniesManager.succeed('createTestAccount', {
|
|
122
123
|
text: commands.testAccount.create.polling.success(testAccountConfig.accountName, resultJson.accountId, derivedAccountId),
|
|
123
124
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
// Only save to config if not using json output
|
|
125
|
+
addJsonOutput(resultJson);
|
|
126
|
+
if (!formatOutputAsJson) {
|
|
129
127
|
try {
|
|
130
128
|
const savedAccountName = await saveAccountToConfig(resultJson.accountId, testAccountConfig.accountName, env, resultJson.personalAccessKey);
|
|
131
129
|
// Inform user if the account name was normalized
|
|
@@ -230,7 +228,9 @@ const builder = makeYargsBuilder(createTestAccountBuilder, command, describe, {
|
|
|
230
228
|
const createTestAccountCommand = {
|
|
231
229
|
command,
|
|
232
230
|
describe,
|
|
233
|
-
handler: makeWrappedYargsHandler('test-account-create', handler
|
|
231
|
+
handler: makeWrappedYargsHandler('test-account-create', handler, {
|
|
232
|
+
jsonOutputSchema: CreateTestAccountSchema,
|
|
233
|
+
}),
|
|
234
234
|
builder,
|
|
235
235
|
};
|
|
236
236
|
export default createTestAccountCommand;
|