@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
|
@@ -120,7 +120,7 @@ const builder = makeYargsBuilder(accountCleanBuilder, command, describe, {
|
|
|
120
120
|
const accountCleanCommand = {
|
|
121
121
|
command,
|
|
122
122
|
describe,
|
|
123
|
-
handler: makeWrappedYargsHandler('
|
|
123
|
+
handler: makeWrappedYargsHandler('account-clean', handler),
|
|
124
124
|
builder,
|
|
125
125
|
};
|
|
126
126
|
export default accountCleanCommand;
|
package/commands/account/list.js
CHANGED
|
@@ -57,7 +57,7 @@ const builder = makeYargsBuilder(accountListBuilder, command, describe, {
|
|
|
57
57
|
const accountListCommand = {
|
|
58
58
|
command,
|
|
59
59
|
describe,
|
|
60
|
-
handler: makeWrappedYargsHandler('
|
|
60
|
+
handler: makeWrappedYargsHandler('account-list', handler),
|
|
61
61
|
builder,
|
|
62
62
|
};
|
|
63
63
|
export default accountListCommand;
|
|
@@ -82,7 +82,7 @@ const builder = makeYargsBuilder(accountRemoveBuilder, command, describe, {
|
|
|
82
82
|
const accountRemoveCommand = {
|
|
83
83
|
command,
|
|
84
84
|
describe,
|
|
85
|
-
handler: makeWrappedYargsHandler('
|
|
85
|
+
handler: makeWrappedYargsHandler('account-remove', handler),
|
|
86
86
|
builder,
|
|
87
87
|
};
|
|
88
88
|
export default accountRemoveCommand;
|
|
@@ -44,7 +44,7 @@ const builder = makeYargsBuilder(accountRenameBuilder, command, describe, {
|
|
|
44
44
|
const accountRenameCommand = {
|
|
45
45
|
command,
|
|
46
46
|
describe,
|
|
47
|
-
handler: makeWrappedYargsHandler('
|
|
47
|
+
handler: makeWrappedYargsHandler('account-rename', handler),
|
|
48
48
|
builder,
|
|
49
49
|
};
|
|
50
50
|
export default accountRenameCommand;
|
package/commands/account/use.js
CHANGED
|
@@ -146,7 +146,7 @@ const builder = makeYargsBuilder(accountUseBuilder, command, describe, {
|
|
|
146
146
|
const accountUseCommand = {
|
|
147
147
|
command,
|
|
148
148
|
describe,
|
|
149
|
-
handler: makeWrappedYargsHandler('
|
|
149
|
+
handler: makeWrappedYargsHandler('account-use', handler),
|
|
150
150
|
builder,
|
|
151
151
|
};
|
|
152
152
|
export default accountUseCommand;
|
package/commands/api.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { CommonArgs, ConfigArgs, EnvironmentArgs, AccountArgs, JSONOutputArgs, YargsCommandModule } from '../types/Yargs.js';
|
|
2
2
|
declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
3
3
|
type HttpMethod = (typeof HTTP_METHODS)[number];
|
|
4
|
-
|
|
4
|
+
type JSONValue = string | number | boolean | null | {
|
|
5
|
+
[key: string]: JSONValue;
|
|
6
|
+
} | Array<JSONValue>;
|
|
7
|
+
export type ApiArgs = CommonArgs & ConfigArgs & EnvironmentArgs & AccountArgs & JSONOutputArgs<Record<string, JSONValue>> & {
|
|
5
8
|
endpoint: string;
|
|
6
9
|
method?: HttpMethod;
|
|
7
10
|
data?: string;
|
package/commands/api.js
CHANGED
|
@@ -29,7 +29,7 @@ function normalizeEndpoint(endpoint) {
|
|
|
29
29
|
return endpoint.startsWith('/') ? endpoint.slice(1) : endpoint;
|
|
30
30
|
}
|
|
31
31
|
async function handler(args) {
|
|
32
|
-
const { endpoint, data, derivedAccountId, json: formatOutputAsJson, exit, addUsageMetadata, } = args;
|
|
32
|
+
const { endpoint, data, derivedAccountId, json: formatOutputAsJson, exit, addUsageMetadata, addJsonOutput, } = args;
|
|
33
33
|
const method = resolveMethod(args);
|
|
34
34
|
addUsageMetadata({ action: method });
|
|
35
35
|
let parsedData;
|
|
@@ -79,10 +79,8 @@ async function handler(args) {
|
|
|
79
79
|
}
|
|
80
80
|
if (response !== undefined) {
|
|
81
81
|
const responseData = response.data;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
82
|
+
addJsonOutput(responseData);
|
|
83
|
+
if (!formatOutputAsJson) {
|
|
86
84
|
uiLogger.log(commands.api.responseLog);
|
|
87
85
|
uiLogger.log(JSON.stringify(responseData, null, 2));
|
|
88
86
|
}
|
|
@@ -99,20 +97,19 @@ async function handler(args) {
|
|
|
99
97
|
}
|
|
100
98
|
debugError(error, errorContext);
|
|
101
99
|
const errorData = error.data;
|
|
102
|
-
if (
|
|
103
|
-
|
|
100
|
+
if (errorData) {
|
|
101
|
+
addJsonOutput(errorData);
|
|
104
102
|
}
|
|
105
|
-
|
|
103
|
+
if (!formatOutputAsJson) {
|
|
106
104
|
if (error.status && error.statusText) {
|
|
107
105
|
uiLogger.error(commands.api.errors.statusLine(error.status, error.statusText));
|
|
108
106
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
uiLogger.error(
|
|
107
|
+
if (errorData) {
|
|
108
|
+
uiLogger.log(JSON.stringify(errorData, null, 2));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
uiLogger.error(error.message);
|
|
114
112
|
}
|
|
115
|
-
uiLogger.error(error.message);
|
|
116
113
|
}
|
|
117
114
|
return exit(EXIT_CODES.ERROR);
|
|
118
115
|
}
|
package/commands/hubdb/list.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
type HubdbListArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs;
|
|
2
|
+
export type HubdbListArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs;
|
|
3
3
|
declare const hubdbListCommand: YargsCommandModule<unknown, HubdbListArgs>;
|
|
4
4
|
export default hubdbListCommand;
|
package/commands/mcp/setup.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { CommonArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
2
|
interface MCPSetupArgs extends CommonArgs {
|
|
3
3
|
client?: string[];
|
|
4
|
+
standalone?: boolean;
|
|
5
|
+
cliVersion?: string;
|
|
4
6
|
}
|
|
5
7
|
declare const mcpSetupCommand: YargsCommandModule<unknown, MCPSetupArgs>;
|
|
6
8
|
export default mcpSetupCommand;
|
package/commands/mcp/setup.js
CHANGED
|
@@ -8,7 +8,11 @@ const describe = commands.mcp.setup.describe;
|
|
|
8
8
|
async function handler(args) {
|
|
9
9
|
const { exit } = args;
|
|
10
10
|
try {
|
|
11
|
-
await configureMcpServer(
|
|
11
|
+
await configureMcpServer({
|
|
12
|
+
targets: args.client,
|
|
13
|
+
standalone: args.standalone,
|
|
14
|
+
cliVersion: args.cliVersion,
|
|
15
|
+
});
|
|
12
16
|
}
|
|
13
17
|
catch (e) {
|
|
14
18
|
return exit(EXIT_CODES.ERROR);
|
|
@@ -21,6 +25,30 @@ function setupBuilder(yargs) {
|
|
|
21
25
|
type: 'array',
|
|
22
26
|
choices: [...supportedTools.map(tool => tool.value)],
|
|
23
27
|
});
|
|
28
|
+
yargs.option('standalone', {
|
|
29
|
+
describe: commands.mcp.setup.args.standalone,
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
});
|
|
32
|
+
yargs.option('cli-version', {
|
|
33
|
+
describe: commands.mcp.setup.args.cliVersion,
|
|
34
|
+
type: 'string',
|
|
35
|
+
});
|
|
36
|
+
yargs.check(argv => {
|
|
37
|
+
if (argv.cliVersion !== undefined && argv.standalone !== true) {
|
|
38
|
+
throw new Error(commands.mcp.setup.errors.cliVersionRequiresStandalone);
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
});
|
|
42
|
+
yargs.example([
|
|
43
|
+
[
|
|
44
|
+
'$0 mcp setup --client claude --no-standalone',
|
|
45
|
+
commands.mcp.setup.examples.nonInteractive,
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
'$0 mcp setup --client cursor --standalone --cli-version 8.0.1',
|
|
49
|
+
commands.mcp.setup.examples.standalone,
|
|
50
|
+
],
|
|
51
|
+
]);
|
|
24
52
|
return yargs;
|
|
25
53
|
}
|
|
26
54
|
const builder = makeYargsBuilder(setupBuilder, command, describe, {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
|
|
2
|
+
import { InstallStatusJsonOutput } from '../../lib/jsonOutput.js';
|
|
3
|
+
export type ProjectInstallStatusArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<InstallStatusJsonOutput>;
|
|
3
4
|
declare const projectInstallStatusCommand: YargsCommandModule<unknown, ProjectInstallStatusArgs>;
|
|
4
5
|
export default projectInstallStatusCommand;
|
|
@@ -5,6 +5,7 @@ import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
|
5
5
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
6
6
|
import { translateForLocalDev } from '@hubspot/project-parsing-lib/translate';
|
|
7
7
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
8
|
+
import { InstallStatusSchema, } from '../../lib/jsonOutput.js';
|
|
8
9
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
9
10
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
10
11
|
import { ApiErrorContext, debugError, logError, } from '../../lib/errorHandlers/index.js';
|
|
@@ -16,7 +17,7 @@ import { APP_AUTH_TYPES } from '../../lib/constants.js';
|
|
|
16
17
|
const command = 'app-install-status';
|
|
17
18
|
const describe = commands.project.installStatus.describe;
|
|
18
19
|
async function handler(args) {
|
|
19
|
-
const { derivedAccountId, formatOutputAsJson, exit } = args;
|
|
20
|
+
const { derivedAccountId, formatOutputAsJson, exit, addJsonOutput } = args;
|
|
20
21
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
21
22
|
if (!projectConfig || !projectDir) {
|
|
22
23
|
uiLogger.error(commands.project.installStatus.errors.noProjectConfig);
|
|
@@ -80,25 +81,24 @@ async function handler(args) {
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
const isInstalled = isInstalledWithScopeGroups || previouslyAuthorizedScopeGroups.length > 0;
|
|
84
|
+
addJsonOutput({
|
|
85
|
+
appId,
|
|
86
|
+
appUid: appNode.uid,
|
|
87
|
+
accountId: derivedAccountId,
|
|
88
|
+
projectId,
|
|
89
|
+
isInstalled,
|
|
90
|
+
isInstalledWithCurrentScopes: isInstalledWithScopeGroups,
|
|
91
|
+
previouslyAuthorizedScopeGroups,
|
|
92
|
+
});
|
|
83
93
|
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
94
|
return exit(isInstalled ? EXIT_CODES.SUCCESS : EXIT_CODES.WARNING);
|
|
94
95
|
}
|
|
96
|
+
if (isInstalledWithScopeGroups) {
|
|
97
|
+
uiLogger.success(commands.project.installStatus.success.installed(appNode.config.name, derivedAccountId));
|
|
98
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
99
|
+
}
|
|
95
100
|
if (isInstalled) {
|
|
96
|
-
|
|
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
|
-
}
|
|
101
|
+
uiLogger.success(commands.project.installStatus.success.installedWithOutdatedScopes(appNode.config.name, derivedAccountId));
|
|
102
102
|
return exit(EXIT_CODES.SUCCESS);
|
|
103
103
|
}
|
|
104
104
|
uiLogger.log(commands.project.installStatus.notInstalled(appNode.config.name, derivedAccountId));
|
|
@@ -127,7 +127,9 @@ const builder = makeYargsBuilder(projectInstallStatusBuilder, command, describe,
|
|
|
127
127
|
const projectInstallStatusCommand = {
|
|
128
128
|
command,
|
|
129
129
|
describe,
|
|
130
|
-
handler: makeWrappedYargsHandler('project-app-install-status', handler
|
|
130
|
+
handler: makeWrappedYargsHandler('project-app-install-status', handler, {
|
|
131
|
+
jsonOutputSchema: InstallStatusSchema,
|
|
132
|
+
}),
|
|
131
133
|
builder,
|
|
132
134
|
};
|
|
133
135
|
export default projectInstallStatusCommand;
|
|
@@ -133,7 +133,6 @@ function projectCreateBuilder(yargs) {
|
|
|
133
133
|
describe: commands.project.create.options.platformVersion.describe,
|
|
134
134
|
type: 'string',
|
|
135
135
|
choices: [
|
|
136
|
-
PLATFORM_VERSIONS.v2025_1,
|
|
137
136
|
PLATFORM_VERSIONS.v2025_2,
|
|
138
137
|
PLATFORM_VERSIONS.v2026_03_BETA,
|
|
139
138
|
PLATFORM_VERSIONS.v2026_03,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
|
|
2
|
+
import { DeployJsonOutput } from '../../lib/jsonOutput.js';
|
|
3
|
+
export type ProjectDeployArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<DeployJsonOutput> & {
|
|
3
4
|
project?: string;
|
|
4
5
|
build?: number;
|
|
5
6
|
buildId?: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
|
|
2
2
|
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
3
|
-
import {
|
|
3
|
+
import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
|
|
4
4
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
5
5
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
6
6
|
import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
|
|
@@ -10,19 +10,21 @@ import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
|
10
10
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
11
11
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
12
12
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
13
|
+
import { DeploySchema } from '../../lib/jsonOutput.js';
|
|
13
14
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
14
15
|
import { loadProfile } from '../../lib/projects/projectProfiles.js';
|
|
15
16
|
import { PROJECT_DEPLOY_TEXT } from '../../lib/constants.js';
|
|
16
17
|
import { commands } from '../../lang/en.js';
|
|
17
18
|
import { handleProjectDeploy, validateBuildIdForDeploy, logDeployErrors, } from '../../lib/projects/deploy.js';
|
|
19
|
+
import { validateBuildForRelease } from '../../lib/projects/release.js';
|
|
20
|
+
import { getLastSuccessfulBuild } from '../../lib/projects/builds.js';
|
|
18
21
|
const command = 'deploy';
|
|
19
22
|
const describe = commands.project.deploy.describe;
|
|
20
23
|
async function handler(args) {
|
|
21
|
-
const { derivedAccountId, project: projectOption, buildId: buildIdOption, force: forceOption, deployLatestBuild: deployLatestBuildOption,
|
|
24
|
+
const { derivedAccountId, project: projectOption, buildId: buildIdOption, force: forceOption, deployLatestBuild: deployLatestBuildOption, profile: profileOption, useEnv: useEnvOption, exit, addUsageMetadata, addJsonOutput, } = args;
|
|
22
25
|
const accountConfig = getConfigAccountById(derivedAccountId);
|
|
23
26
|
const accountType = accountConfig && accountConfig.accountType;
|
|
24
27
|
let targetAccountId;
|
|
25
|
-
const jsonOutput = {};
|
|
26
28
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
27
29
|
let isInProjectDirectory = false;
|
|
28
30
|
// Validate project config, but it's valid to run this command from outside a project dir
|
|
@@ -79,16 +81,21 @@ async function handler(args) {
|
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
else {
|
|
84
|
+
const lastSuccessfulBuild = await getLastSuccessfulBuild(targetAccountId, projectName, latestBuild);
|
|
85
|
+
if (!lastSuccessfulBuild) {
|
|
86
|
+
uiLogger.error(commands.project.deploy.errors.noSuccessfulBuilds);
|
|
87
|
+
return exit(EXIT_CODES.ERROR);
|
|
88
|
+
}
|
|
82
89
|
if (deployLatestBuildOption) {
|
|
83
|
-
buildIdToDeploy =
|
|
90
|
+
buildIdToDeploy = lastSuccessfulBuild.buildId;
|
|
84
91
|
}
|
|
85
92
|
else {
|
|
86
93
|
const deployBuildIdPromptResponse = await promptUser({
|
|
87
94
|
name: 'buildId',
|
|
88
95
|
message: commands.project.deploy.deployBuildIdPrompt,
|
|
89
|
-
default:
|
|
96
|
+
default: lastSuccessfulBuild.buildId === deployedBuildId
|
|
90
97
|
? undefined
|
|
91
|
-
:
|
|
98
|
+
: lastSuccessfulBuild.buildId,
|
|
92
99
|
validate: buildId => validateBuildIdForDeploy(buildId, deployedBuildId, latestBuild.buildId, projectName, targetAccountId),
|
|
93
100
|
});
|
|
94
101
|
buildIdToDeploy = deployBuildIdPromptResponse.buildId;
|
|
@@ -98,22 +105,33 @@ async function handler(args) {
|
|
|
98
105
|
uiLogger.error(commands.project.deploy.errors.noBuildId);
|
|
99
106
|
return exit(EXIT_CODES.ERROR);
|
|
100
107
|
}
|
|
108
|
+
try {
|
|
109
|
+
const supportsReleases = await validateBuildForRelease(targetAccountId, projectName, buildIdToDeploy);
|
|
110
|
+
// The deploy verb is not compatible with builds that leverage releases. Use release create instead.
|
|
111
|
+
if (supportsReleases) {
|
|
112
|
+
uiLogger.error(commands.project.deploy.errors.notSupportedForBuildVersion);
|
|
113
|
+
return exit(EXIT_CODES.ERROR);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return exit(EXIT_CODES.ERROR);
|
|
118
|
+
}
|
|
101
119
|
const deployResult = await handleProjectDeploy(targetAccountId, projectName, buildIdToDeploy, isLegacyProject(projectConfig?.platformVersion), forceOption);
|
|
102
120
|
if (!deployResult) {
|
|
103
121
|
return exit(EXIT_CODES.ERROR);
|
|
104
122
|
}
|
|
105
|
-
else
|
|
106
|
-
|
|
123
|
+
else {
|
|
124
|
+
addJsonOutput({ deployId: deployResult.deployId });
|
|
107
125
|
}
|
|
108
126
|
if (deployResult.status === PROJECT_DEPLOY_TEXT.STATES.SUCCESS) {
|
|
109
127
|
deploySuccess = true;
|
|
110
128
|
}
|
|
111
129
|
}
|
|
112
130
|
catch (e) {
|
|
113
|
-
if (
|
|
131
|
+
if (isSpecifiedError(e, { statusCode: 404 })) {
|
|
114
132
|
uiLogger.error(commands.project.deploy.errors.projectNotFound(targetAccountId, projectName));
|
|
115
133
|
}
|
|
116
|
-
else if (
|
|
134
|
+
else if (isSpecifiedError(e, { statusCode: 400 })) {
|
|
117
135
|
if (e.data?.message && e.data?.errors) {
|
|
118
136
|
logDeployErrors(e.data);
|
|
119
137
|
}
|
|
@@ -129,9 +147,6 @@ async function handler(args) {
|
|
|
129
147
|
}
|
|
130
148
|
return exit(EXIT_CODES.ERROR);
|
|
131
149
|
}
|
|
132
|
-
if (formatOutputAsJson) {
|
|
133
|
-
uiLogger.json(jsonOutput);
|
|
134
|
-
}
|
|
135
150
|
if (deploySuccess) {
|
|
136
151
|
return exit(EXIT_CODES.SUCCESS);
|
|
137
152
|
}
|
|
@@ -194,6 +209,8 @@ const projectDeployCommand = {
|
|
|
194
209
|
command,
|
|
195
210
|
describe,
|
|
196
211
|
builder,
|
|
197
|
-
handler: makeWrappedYargsHandler('project-deploy', handler
|
|
212
|
+
handler: makeWrappedYargsHandler('project-deploy', handler, {
|
|
213
|
+
jsonOutputSchema: DeploySchema,
|
|
214
|
+
}),
|
|
198
215
|
};
|
|
199
216
|
export default projectDeployCommand;
|
|
@@ -3,7 +3,6 @@ import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/
|
|
|
3
3
|
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
4
4
|
import { uiLine } from '../../../lib/ui/index.js';
|
|
5
5
|
import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
|
|
6
|
-
import { deprecatedProjectDevFlow } from './deprecatedFlow.js';
|
|
7
6
|
import { unifiedProjectDevFlow } from './unifiedFlow.js';
|
|
8
7
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
9
8
|
import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
|
|
@@ -16,17 +15,8 @@ import { isPromptExitError } from '../../../lib/errors/PromptExitError.js';
|
|
|
16
15
|
import { LOCAL_DEV_DEFAULT_PORT } from '../../../lib/constants.js';
|
|
17
16
|
const command = 'dev';
|
|
18
17
|
const describe = commands.project.dev.describe;
|
|
19
|
-
function validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV2) {
|
|
20
|
-
// Legacy projects do not support targetTestingAccount and targetProjectAccount
|
|
21
|
-
if (testingAccount && projectAccount && !useV2) {
|
|
22
|
-
throw new Error(commands.project.dev.errors.unsupportedAccountFlagLegacy);
|
|
23
|
-
}
|
|
24
|
-
if (userProvidedAccount && useV2) {
|
|
25
|
-
throw new Error(commands.project.dev.errors.unsupportedAccountFlagV2);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
18
|
async function handler(args) {
|
|
29
|
-
const { derivedAccountId,
|
|
19
|
+
const { derivedAccountId, testingAccount, projectAccount, profile: profileOption, exit, addUsageMetadata, } = args;
|
|
30
20
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
31
21
|
try {
|
|
32
22
|
validateProjectConfig(projectConfig, projectDir);
|
|
@@ -35,28 +25,18 @@ async function handler(args) {
|
|
|
35
25
|
logError(error);
|
|
36
26
|
return exit(EXIT_CODES.ERROR);
|
|
37
27
|
}
|
|
38
|
-
const useV2Projects = !isLegacyProject(projectConfig.platformVersion);
|
|
39
28
|
if (!projectDir) {
|
|
40
29
|
uiLogger.error(commands.project.dev.errors.noProjectConfig);
|
|
41
30
|
return exit(EXIT_CODES.ERROR);
|
|
42
31
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
logError(error);
|
|
32
|
+
if (isLegacyProject(projectConfig.platformVersion)) {
|
|
33
|
+
uiLogger.error(commands.project.dev.errors.unsupportedPlatformVersion(projectConfig.platformVersion));
|
|
48
34
|
return exit(EXIT_CODES.ERROR);
|
|
49
35
|
}
|
|
50
36
|
uiLogger.log(commands.project.dev.logs.header);
|
|
51
|
-
|
|
52
|
-
uiLogger.log(commands.project.dev.logs.learnMoreMessageV2);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
uiLogger.log(commands.project.dev.logs.learnMoreMessageLegacy);
|
|
56
|
-
}
|
|
37
|
+
uiLogger.log(commands.project.dev.logs.learnMoreMessageV2);
|
|
57
38
|
let targetProjectAccountId;
|
|
58
39
|
let profile;
|
|
59
|
-
// Using the new --projectAccount flag
|
|
60
40
|
if (projectAccount) {
|
|
61
41
|
targetProjectAccountId =
|
|
62
42
|
getConfigAccountIfExists(projectAccount)?.accountId;
|
|
@@ -64,14 +44,8 @@ async function handler(args) {
|
|
|
64
44
|
uiLogger.log('');
|
|
65
45
|
uiLogger.log(commands.project.dev.logs.projectAccountFlagExplanation(targetProjectAccountId));
|
|
66
46
|
}
|
|
67
|
-
// Using the legacy --account flag
|
|
68
47
|
}
|
|
69
|
-
|
|
70
|
-
targetProjectAccountId = derivedAccountId;
|
|
71
|
-
}
|
|
72
|
-
// Determine profile name: from flag or prompt
|
|
73
|
-
if (!targetProjectAccountId &&
|
|
74
|
-
!isLegacyProject(projectConfig.platformVersion)) {
|
|
48
|
+
if (!targetProjectAccountId) {
|
|
75
49
|
const profileName = await projectProfilePrompt(projectDir, projectConfig, profileOption);
|
|
76
50
|
if (profileName) {
|
|
77
51
|
try {
|
|
@@ -88,36 +62,23 @@ async function handler(args) {
|
|
|
88
62
|
}
|
|
89
63
|
}
|
|
90
64
|
if (!targetProjectAccountId) {
|
|
91
|
-
// The user is not using profile or account flags, so we can use the derived accountId
|
|
92
65
|
targetProjectAccountId = derivedAccountId;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
uiLogger.log(commands.project.dev.logs.defaultProjectAccountExplanation(targetProjectAccountId));
|
|
96
|
-
}
|
|
66
|
+
uiLogger.log('');
|
|
67
|
+
uiLogger.log(commands.project.dev.logs.defaultProjectAccountExplanation(targetProjectAccountId));
|
|
97
68
|
}
|
|
98
69
|
addUsageMetadata({ accountId: targetProjectAccountId ?? undefined });
|
|
99
70
|
try {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
await deprecatedProjectDevFlow({
|
|
115
|
-
args,
|
|
116
|
-
accountId: targetProjectAccountId,
|
|
117
|
-
projectConfig,
|
|
118
|
-
projectDir,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
71
|
+
const targetTestingAccountId = testingAccount
|
|
72
|
+
? getConfigAccountIfExists(testingAccount)?.accountId
|
|
73
|
+
: undefined;
|
|
74
|
+
await unifiedProjectDevFlow({
|
|
75
|
+
args,
|
|
76
|
+
targetProjectAccountId,
|
|
77
|
+
providedTargetTestingAccountId: targetTestingAccountId,
|
|
78
|
+
projectConfig,
|
|
79
|
+
projectDir,
|
|
80
|
+
profileConfig: profile,
|
|
81
|
+
});
|
|
121
82
|
}
|
|
122
83
|
catch (e) {
|
|
123
84
|
if (isPromptExitError(e)) {
|
|
@@ -144,19 +105,12 @@ function projectDevBuilder(yargs) {
|
|
|
144
105
|
description: commands.project.dev.options.projectAccount,
|
|
145
106
|
implies: ['testingAccount'],
|
|
146
107
|
});
|
|
147
|
-
yargs.option('account', {
|
|
148
|
-
alias: 'a',
|
|
149
|
-
describe: '',
|
|
150
|
-
type: 'string',
|
|
151
|
-
description: commands.project.dev.options.account,
|
|
152
|
-
});
|
|
153
108
|
yargs.option('port', {
|
|
154
109
|
type: 'number',
|
|
155
110
|
description: commands.project.dev.options.port,
|
|
156
111
|
default: LOCAL_DEV_DEFAULT_PORT,
|
|
157
112
|
});
|
|
158
113
|
yargs.example([['$0 project dev', commands.project.dev.examples.default]]);
|
|
159
|
-
yargs.conflicts('profile', 'account');
|
|
160
114
|
yargs.conflicts('profile', 'testing-account');
|
|
161
115
|
yargs.conflicts('profile', 'project-account');
|
|
162
116
|
return yargs;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
|
|
2
|
+
import { ProjectInfoJsonOutput } from '../../lib/jsonOutput.js';
|
|
3
|
+
export type ProjectInfoArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ProjectInfoJsonOutput>;
|
|
3
4
|
declare const projectInfoCommand: YargsCommandModule<unknown, ProjectInfoArgs>;
|
|
4
5
|
export default projectInfoCommand;
|
package/commands/project/info.js
CHANGED
|
@@ -8,11 +8,12 @@ import { commands } from '../../lang/en.js';
|
|
|
8
8
|
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
9
9
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
10
10
|
import { getProjectInfo, logProjectInfo, } from '../../lib/projects/projectInfo.js';
|
|
11
|
+
import { ProjectInfoSchema, } from '../../lib/jsonOutput.js';
|
|
11
12
|
const command = 'info';
|
|
12
13
|
const describe = commands.project.info.describe;
|
|
13
14
|
const verboseDescribe = commands.project.info.verboseDescribe;
|
|
14
15
|
async function handler(args) {
|
|
15
|
-
const { derivedAccountId, formatOutputAsJson, exit } = args;
|
|
16
|
+
const { derivedAccountId, formatOutputAsJson, exit, addJsonOutput } = args;
|
|
16
17
|
const { projectConfig } = await getProjectConfig();
|
|
17
18
|
if (!projectConfig) {
|
|
18
19
|
uiLogger.error(commands.project.info.errors.noProjectConfig);
|
|
@@ -39,11 +40,10 @@ async function handler(args) {
|
|
|
39
40
|
return exit(EXIT_CODES.ERROR);
|
|
40
41
|
}
|
|
41
42
|
const projectInfo = await getProjectInfo(project, projectConfig.platformVersion, derivedAccountId);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
addJsonOutput(projectInfo);
|
|
44
|
+
if (!formatOutputAsJson) {
|
|
45
|
+
logProjectInfo(projectInfo);
|
|
45
46
|
}
|
|
46
|
-
logProjectInfo(projectInfo);
|
|
47
47
|
}
|
|
48
48
|
function projectInfoBuilder(yargs) {
|
|
49
49
|
yargs.example([
|
|
@@ -62,7 +62,9 @@ const builder = makeYargsBuilder(projectInfoBuilder, command, verboseDescribe, {
|
|
|
62
62
|
const projectInfoCommand = {
|
|
63
63
|
command,
|
|
64
64
|
describe,
|
|
65
|
-
handler: makeWrappedYargsHandler('project-info', handler
|
|
65
|
+
handler: makeWrappedYargsHandler('project-info', handler, {
|
|
66
|
+
jsonOutputSchema: ProjectInfoSchema,
|
|
67
|
+
}),
|
|
66
68
|
builder,
|
|
67
69
|
};
|
|
68
70
|
export default projectInfoCommand;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
|
|
2
|
+
import { InstallAppJsonOutput } from '../../lib/jsonOutput.js';
|
|
3
|
+
export type ProjectInstallAppArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<InstallAppJsonOutput> & {
|
|
3
4
|
force: boolean;
|
|
4
5
|
profile?: string;
|
|
5
6
|
};
|