@hubspot/cli 8.6.0 → 8.7.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/api/releases.d.ts +36 -0
- package/api/releases.js +41 -0
- package/bin/cli.js +3 -3
- package/commands/account/auth.js +2 -2
- package/commands/account/clean.js +2 -2
- package/commands/account/createOverride.js +2 -2
- package/commands/account/info.js +2 -2
- package/commands/account/link.js +2 -2
- package/commands/account/list.js +2 -2
- package/commands/account/remove.js +2 -2
- package/commands/account/removeOverride.js +2 -2
- package/commands/account/rename.js +2 -2
- package/commands/account/unlink.js +2 -2
- package/commands/account/use.js +2 -2
- package/commands/api.js +2 -2
- package/commands/app/migrate.js +2 -2
- package/commands/app/secret/add.js +2 -2
- package/commands/app/secret/delete.js +2 -2
- package/commands/app/secret/list.js +2 -2
- package/commands/app/secret/update.js +2 -2
- package/commands/auth.js +2 -2
- package/commands/cms/app/create.js +2 -2
- package/commands/cms/convertFields.js +2 -2
- package/commands/cms/delete.js +2 -2
- package/commands/cms/fetch.js +2 -2
- package/commands/cms/function/create.js +2 -2
- package/commands/cms/function/deploy.js +2 -2
- package/commands/cms/function/list.js +2 -2
- package/commands/cms/function/logs.js +2 -2
- package/commands/cms/function/server.js +2 -2
- package/commands/cms/getReactModule.js +2 -2
- package/commands/cms/lighthouseScore.js +2 -2
- package/commands/cms/lint.js +2 -2
- package/commands/cms/list.js +2 -2
- package/commands/cms/module/create.js +8 -2
- package/commands/cms/module/marketplace-validate.js +2 -2
- package/commands/cms/mv.js +2 -2
- package/commands/cms/template/create.js +2 -2
- package/commands/cms/theme/create.js +2 -2
- package/commands/cms/theme/generate-selectors.js +2 -2
- package/commands/cms/theme/marketplace-validate.js +2 -2
- package/commands/cms/theme/preview.js +2 -2
- package/commands/cms/upload.js +2 -2
- package/commands/cms/watch.js +2 -2
- package/commands/cms/webpack/create.js +2 -2
- package/commands/completion.js +2 -2
- package/commands/config/migrate.js +2 -2
- package/commands/config/set.js +2 -2
- package/commands/customObject/create.js +2 -2
- package/commands/customObject/createSchema.js +2 -2
- package/commands/customObject/deleteSchema.js +2 -2
- package/commands/customObject/fetchAllSchemas.js +2 -2
- package/commands/customObject/fetchSchema.js +2 -2
- package/commands/customObject/listSchemas.js +2 -2
- package/commands/customObject/updateSchema.js +2 -2
- package/commands/doctor.js +2 -2
- package/commands/feedback.js +2 -2
- package/commands/filemanager/fetch.js +2 -2
- package/commands/filemanager/upload.js +2 -2
- package/commands/getStarted.js +2 -2
- package/commands/hubdb/clear.js +2 -2
- package/commands/hubdb/create.js +2 -2
- package/commands/hubdb/delete.js +2 -2
- package/commands/hubdb/fetch.js +2 -2
- package/commands/hubdb/list.js +2 -2
- package/commands/init.js +2 -2
- package/commands/mcp/setup.js +2 -2
- package/commands/mcp/start.js +2 -2
- package/commands/open.js +2 -2
- package/commands/project/add.js +2 -2
- package/commands/project/appInstallStatus.d.ts +2 -2
- package/commands/project/appInstallStatus.js +3 -2
- package/commands/project/create.js +2 -2
- package/commands/project/delete.js +2 -2
- package/commands/project/deploy.js +2 -2
- package/commands/project/dev/index.js +2 -2
- package/commands/project/download.js +2 -2
- package/commands/project/info.d.ts +2 -2
- package/commands/project/info.js +3 -2
- package/commands/project/installDeps.js +2 -2
- package/commands/project/lint.js +7 -5
- package/commands/project/list.d.ts +2 -2
- package/commands/project/list.js +3 -2
- package/commands/project/listBuilds.js +2 -2
- package/commands/project/logs.js +2 -2
- package/commands/project/migrate.js +2 -2
- package/commands/project/open.js +2 -2
- package/commands/project/profile/add.js +2 -2
- package/commands/project/profile/delete.js +2 -2
- package/commands/project/release/create.d.ts +7 -0
- package/commands/project/release/create.js +159 -0
- package/commands/project/release/info.d.ts +6 -0
- package/commands/project/release/info.js +147 -0
- package/commands/project/release/list.d.ts +6 -0
- package/commands/project/release/list.js +111 -0
- package/commands/project/release.d.ts +3 -0
- package/commands/project/release.js +20 -0
- package/commands/project/updateDeps.js +2 -2
- package/commands/project/upload.d.ts +3 -0
- package/commands/project/upload.js +77 -9
- package/commands/project/validate.js +2 -2
- package/commands/project/watch.js +2 -2
- package/commands/project.js +2 -0
- package/commands/sandbox/create.js +2 -2
- package/commands/sandbox/delete.js +2 -2
- package/commands/secret/addSecret.js +2 -2
- package/commands/secret/deleteSecret.js +2 -2
- package/commands/secret/listSecret.js +2 -2
- package/commands/secret/updateSecret.js +2 -2
- package/commands/testAccount/create.js +2 -2
- package/commands/testAccount/createConfig.js +2 -2
- package/commands/testAccount/delete.js +2 -2
- package/commands/testAccount/importData.js +2 -2
- package/commands/upgrade.js +2 -2
- package/lang/en.d.ts +92 -0
- package/lang/en.js +92 -0
- package/lib/api/usageTracking.d.ts +29 -0
- package/lib/api/usageTracking.js +28 -0
- package/lib/commonOpts.js +0 -1
- package/lib/constants.d.ts +1 -0
- package/lib/constants.js +1 -0
- package/lib/projects/localDev/helpers/project.js +1 -1
- package/lib/projects/npmAuditOnUpload.d.ts +10 -0
- package/lib/projects/npmAuditOnUpload.js +73 -0
- package/lib/projects/pollProjectBuildAndDeploy.d.ts +5 -1
- package/lib/projects/pollProjectBuildAndDeploy.js +3 -2
- package/lib/projects/preview.d.ts +7 -0
- package/lib/projects/preview.js +48 -0
- package/lib/projects/uieLinting.d.ts +4 -0
- package/lib/projects/uieLinting.js +36 -1
- package/lib/projects/upload.d.ts +3 -1
- package/lib/projects/upload.js +26 -6
- package/lib/projects/validateLintConfigOnUpload.d.ts +9 -0
- package/lib/projects/validateLintConfigOnUpload.js +45 -0
- package/lib/projects/workspaces.d.ts +11 -1
- package/lib/projects/workspaces.js +27 -12
- package/lib/usageTracking.d.ts +7 -17
- package/lib/usageTracking.js +43 -29
- package/lib/yargs/makeWrappedYargsHandler.d.ts +3 -0
- package/lib/yargs/{makeYargsHandlerWithUsageTracking.js → makeWrappedYargsHandler.js} +29 -3
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +2 -2
- package/mcp-server/tools/cms/HsCreateModuleTool.js +4 -5
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +2 -2
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +2 -3
- package/mcp-server/tools/cms/HsListFunctionsTool.js +2 -3
- package/mcp-server/tools/cms/HsListTool.js +2 -2
- package/mcp-server/utils/toolUsageTracking.js +10 -6
- package/package.json +4 -4
- package/lib/yargs/makeYargsHandlerWithUsageTracking.d.ts +0 -3
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { fetchProject, getBuildStatus, } from '@hubspot/local-dev-lib/api/projects';
|
|
2
|
+
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
3
|
+
import { logError, ApiErrorContext } from '../../../lib/errorHandlers/index.js';
|
|
4
|
+
import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/config.js';
|
|
5
|
+
import { confirmPrompt } from '../../../lib/prompts/promptUtils.js';
|
|
6
|
+
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
7
|
+
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
8
|
+
import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
|
|
9
|
+
import { commands } from '../../../lang/en.js';
|
|
10
|
+
import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
|
|
11
|
+
import { createRelease } from '../../../api/releases.js';
|
|
12
|
+
const command = 'create';
|
|
13
|
+
// const describe = commands.project.release.create.describe;
|
|
14
|
+
const describe = undefined;
|
|
15
|
+
// const verboseDescribe = commands.project.release.create.verboseDescribe;
|
|
16
|
+
const verboseDescribe = undefined;
|
|
17
|
+
async function resolveBuildId(accountId, projectName, buildOption) {
|
|
18
|
+
const { data: { deployedBuildId }, } = await fetchProject(accountId, projectName);
|
|
19
|
+
if (buildOption) {
|
|
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;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function handler(args) {
|
|
68
|
+
const { exit, derivedAccountId, build: buildOption, json: formatOutputAsJson, force, } = args;
|
|
69
|
+
const { projectConfig, projectDir } = await getProjectConfig();
|
|
70
|
+
try {
|
|
71
|
+
validateProjectConfig(projectConfig, projectDir);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
logError(error);
|
|
75
|
+
return exit(EXIT_CODES.ERROR);
|
|
76
|
+
}
|
|
77
|
+
const projectName = projectConfig.name;
|
|
78
|
+
let buildId;
|
|
79
|
+
try {
|
|
80
|
+
buildId = await resolveBuildId(derivedAccountId, projectName, buildOption);
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
if (isHubSpotHttpError(e) && e.status === 404) {
|
|
84
|
+
uiLogger.error(commands.project.release.create.errors.projectNotFound(derivedAccountId, projectName));
|
|
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);
|
|
94
|
+
}
|
|
95
|
+
return exit(EXIT_CODES.ERROR);
|
|
96
|
+
}
|
|
97
|
+
if (buildOption) {
|
|
98
|
+
try {
|
|
99
|
+
await validateBuild(derivedAccountId, projectName, buildId);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return exit(EXIT_CODES.ERROR);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!formatOutputAsJson && !force) {
|
|
106
|
+
const confirmed = await confirmPrompt(commands.project.release.create.confirmPrompt(projectName, buildId));
|
|
107
|
+
if (!confirmed) {
|
|
108
|
+
uiLogger.log(commands.project.release.create.cancelled);
|
|
109
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
await executeRelease(derivedAccountId, projectName, buildId, !!formatOutputAsJson);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return exit(EXIT_CODES.ERROR);
|
|
117
|
+
}
|
|
118
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
119
|
+
}
|
|
120
|
+
function projectReleaseCreateBuilder(yargs) {
|
|
121
|
+
yargs.options({
|
|
122
|
+
build: {
|
|
123
|
+
alias: ['build-id'],
|
|
124
|
+
describe: commands.project.release.create.options.build,
|
|
125
|
+
type: 'number',
|
|
126
|
+
},
|
|
127
|
+
force: {
|
|
128
|
+
alias: ['f'],
|
|
129
|
+
describe: commands.project.release.create.options.force,
|
|
130
|
+
default: false,
|
|
131
|
+
type: 'boolean',
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
yargs.example([
|
|
135
|
+
[
|
|
136
|
+
'$0 project release create',
|
|
137
|
+
commands.project.release.create.examples.default,
|
|
138
|
+
],
|
|
139
|
+
[
|
|
140
|
+
'$0 project release create --build=5',
|
|
141
|
+
commands.project.release.create.examples.withBuild,
|
|
142
|
+
],
|
|
143
|
+
]);
|
|
144
|
+
return yargs;
|
|
145
|
+
}
|
|
146
|
+
const builder = makeYargsBuilder(projectReleaseCreateBuilder, command, verboseDescribe, {
|
|
147
|
+
useGlobalOptions: true,
|
|
148
|
+
useConfigOptions: true,
|
|
149
|
+
useAccountOptions: true,
|
|
150
|
+
useEnvironmentOptions: true,
|
|
151
|
+
useJSONOutputOptions: true,
|
|
152
|
+
});
|
|
153
|
+
const projectReleaseCreateCommand = {
|
|
154
|
+
command,
|
|
155
|
+
describe,
|
|
156
|
+
builder,
|
|
157
|
+
handler: makeWrappedYargsHandler('project-release-create', handler),
|
|
158
|
+
};
|
|
159
|
+
export default projectReleaseCreateCommand;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../../types/Yargs.js';
|
|
2
|
+
export type ProjectReleaseInfoArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs & {
|
|
3
|
+
tag?: string;
|
|
4
|
+
};
|
|
5
|
+
declare const projectReleaseInfoCommand: YargsCommandModule<unknown, ProjectReleaseInfoArgs>;
|
|
6
|
+
export default projectReleaseInfoCommand;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { getReleaseInfo, listReleases } from '../../../api/releases.js';
|
|
2
|
+
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
3
|
+
import { logError, ApiErrorContext } from '../../../lib/errorHandlers/index.js';
|
|
4
|
+
import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/config.js';
|
|
5
|
+
import { listPrompt } from '../../../lib/prompts/promptUtils.js';
|
|
6
|
+
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
7
|
+
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
8
|
+
import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
|
|
9
|
+
import { commands } from '../../../lang/en.js';
|
|
10
|
+
import { renderTable } from '../../../ui/render.js';
|
|
11
|
+
import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
|
|
12
|
+
import { isPromptExitError } from '../../../lib/errors/PromptExitError.js';
|
|
13
|
+
import { mapToUserFacingType } from '@hubspot/project-parsing-lib/transform';
|
|
14
|
+
import { AUTO_GENERATED_COMPONENT_TYPES } from '@hubspot/project-parsing-lib/constants';
|
|
15
|
+
const command = 'info';
|
|
16
|
+
// const describe = commands.project.release.info.describe;
|
|
17
|
+
const describe = undefined;
|
|
18
|
+
// const verboseDescribe = commands.project.release.info.verboseDescribe;
|
|
19
|
+
const verboseDescribe = undefined;
|
|
20
|
+
function normalizeTag(rawTag) {
|
|
21
|
+
return rawTag.startsWith('v') ? rawTag : `v${rawTag}`;
|
|
22
|
+
}
|
|
23
|
+
async function selectReleasePrompt(accountId, projectName) {
|
|
24
|
+
const { data: { results, paging }, } = await listReleases(accountId, projectName);
|
|
25
|
+
if (results.length === 0) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
if (paging?.next?.after) {
|
|
29
|
+
uiLogger.info(commands.project.release.info.moreReleasesHint);
|
|
30
|
+
}
|
|
31
|
+
return listPrompt(commands.project.release.info.selectRelease(projectName), {
|
|
32
|
+
choices: results.map(release => ({
|
|
33
|
+
name: `${release.releaseTag} (build #${release.buildId}, ${new Date(release.createdAt).toLocaleString()})`,
|
|
34
|
+
value: release.releaseTag,
|
|
35
|
+
})),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async function handler(args) {
|
|
39
|
+
const { derivedAccountId, tag: rawTag, json: formatOutputAsJson, exit, } = args;
|
|
40
|
+
const { projectConfig, projectDir } = await getProjectConfig();
|
|
41
|
+
try {
|
|
42
|
+
validateProjectConfig(projectConfig, projectDir);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
logError(error);
|
|
46
|
+
return exit(EXIT_CODES.ERROR);
|
|
47
|
+
}
|
|
48
|
+
const projectName = projectConfig.name;
|
|
49
|
+
let tag;
|
|
50
|
+
if (rawTag) {
|
|
51
|
+
tag = normalizeTag(rawTag);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
try {
|
|
55
|
+
const selected = await selectReleasePrompt(derivedAccountId, projectName);
|
|
56
|
+
if (!selected) {
|
|
57
|
+
uiLogger.error(commands.project.release.info.errors.noReleases);
|
|
58
|
+
return exit(EXIT_CODES.ERROR);
|
|
59
|
+
}
|
|
60
|
+
tag = selected;
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
if (isPromptExitError(e)) {
|
|
64
|
+
throw e;
|
|
65
|
+
}
|
|
66
|
+
logError(e);
|
|
67
|
+
return exit(EXIT_CODES.ERROR);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const { data: release } = await getReleaseInfo(derivedAccountId, projectName, tag);
|
|
72
|
+
if (formatOutputAsJson) {
|
|
73
|
+
uiLogger.json(release);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
uiLogger.log(commands.project.release.info.releaseDetails(release.releaseTag, projectName));
|
|
77
|
+
renderTable(['Release', 'Build', 'Created'], [
|
|
78
|
+
[
|
|
79
|
+
release.releaseTag,
|
|
80
|
+
`#${release.buildId}`,
|
|
81
|
+
new Date(release.createdAt).toLocaleString(),
|
|
82
|
+
],
|
|
83
|
+
]);
|
|
84
|
+
const visibleComponents = (release.components ?? []).filter(component => !AUTO_GENERATED_COMPONENT_TYPES.includes(component.buildType));
|
|
85
|
+
if (visibleComponents.length > 0) {
|
|
86
|
+
uiLogger.log('');
|
|
87
|
+
uiLogger.log(commands.project.release.info.components);
|
|
88
|
+
const componentRows = visibleComponents.map(component => [
|
|
89
|
+
mapToUserFacingType(component.buildType),
|
|
90
|
+
component.buildName ?? '',
|
|
91
|
+
component.rootPath ?? '',
|
|
92
|
+
]);
|
|
93
|
+
renderTable(['Type', 'Name', 'Path'], componentRows);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
uiLogger.log('');
|
|
97
|
+
uiLogger.log(commands.project.release.info.noComponents);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
if (isHubSpotHttpError(e) && e.status === 404) {
|
|
103
|
+
uiLogger.error(commands.project.release.info.errors.releaseNotFound(tag, projectName));
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
logError(e, new ApiErrorContext({
|
|
107
|
+
accountId: derivedAccountId,
|
|
108
|
+
request: 'project release info',
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
return exit(EXIT_CODES.ERROR);
|
|
112
|
+
}
|
|
113
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
114
|
+
}
|
|
115
|
+
function projectReleaseInfoBuilder(yargs) {
|
|
116
|
+
yargs.options({
|
|
117
|
+
tag: {
|
|
118
|
+
describe: commands.project.release.info.options.tag,
|
|
119
|
+
type: 'string',
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
yargs.example([
|
|
123
|
+
[
|
|
124
|
+
'$0 project release info --tag=v1.0.0',
|
|
125
|
+
commands.project.release.info.examples.default,
|
|
126
|
+
],
|
|
127
|
+
[
|
|
128
|
+
'$0 project release info --tag=v1.0.0 --json',
|
|
129
|
+
commands.project.release.info.examples.json,
|
|
130
|
+
],
|
|
131
|
+
]);
|
|
132
|
+
return yargs;
|
|
133
|
+
}
|
|
134
|
+
const builder = makeYargsBuilder(projectReleaseInfoBuilder, command, verboseDescribe, {
|
|
135
|
+
useGlobalOptions: true,
|
|
136
|
+
useConfigOptions: true,
|
|
137
|
+
useAccountOptions: true,
|
|
138
|
+
useEnvironmentOptions: true,
|
|
139
|
+
useJSONOutputOptions: true,
|
|
140
|
+
});
|
|
141
|
+
const projectReleaseInfoCommand = {
|
|
142
|
+
command,
|
|
143
|
+
describe,
|
|
144
|
+
builder,
|
|
145
|
+
handler: makeWrappedYargsHandler('project-release-info', handler),
|
|
146
|
+
};
|
|
147
|
+
export default projectReleaseInfoCommand;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../../types/Yargs.js';
|
|
2
|
+
export type ProjectReleaseListArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs & {
|
|
3
|
+
limit?: number;
|
|
4
|
+
};
|
|
5
|
+
declare const projectReleaseListCommand: YargsCommandModule<unknown, ProjectReleaseListArgs>;
|
|
6
|
+
export default projectReleaseListCommand;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { listReleases } from '../../../api/releases.js';
|
|
2
|
+
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
3
|
+
import { isPromptExitError } from '../../../lib/errors/PromptExitError.js';
|
|
4
|
+
import { logError, ApiErrorContext } from '../../../lib/errorHandlers/index.js';
|
|
5
|
+
import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/config.js';
|
|
6
|
+
import { promptUser } from '../../../lib/prompts/promptUtils.js';
|
|
7
|
+
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
8
|
+
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
9
|
+
import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
|
|
10
|
+
import { commands } from '../../../lang/en.js';
|
|
11
|
+
import { renderTable } from '../../../ui/render.js';
|
|
12
|
+
import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
|
|
13
|
+
const command = 'list';
|
|
14
|
+
// const describe = commands.project.release.list.describe;
|
|
15
|
+
const describe = undefined;
|
|
16
|
+
// const verboseDescribe = commands.project.release.list.verboseDescribe;
|
|
17
|
+
const verboseDescribe = undefined;
|
|
18
|
+
async function fetchAndDisplayReleases(accountId, projectName, options) {
|
|
19
|
+
const { data: { results, paging }, } = await listReleases(accountId, projectName, options);
|
|
20
|
+
uiLogger.log(commands.project.release.list.showingReleases(results.length, projectName));
|
|
21
|
+
if (results.length === 0) {
|
|
22
|
+
uiLogger.log(commands.project.release.list.noReleases);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const rows = results.map(release => [
|
|
26
|
+
release.releaseTag,
|
|
27
|
+
`#${release.buildId}`,
|
|
28
|
+
new Date(release.createdAt).toLocaleString(),
|
|
29
|
+
]);
|
|
30
|
+
renderTable(['Release', 'Build', 'Created'], rows);
|
|
31
|
+
}
|
|
32
|
+
if (paging?.next?.after) {
|
|
33
|
+
await promptUser({
|
|
34
|
+
name: 'more',
|
|
35
|
+
message: commands.project.release.list.continueOrExitPrompt,
|
|
36
|
+
});
|
|
37
|
+
await fetchAndDisplayReleases(accountId, projectName, {
|
|
38
|
+
limit: options.limit,
|
|
39
|
+
after: paging.next.after,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function handler(args) {
|
|
44
|
+
const { derivedAccountId, limit, json: formatOutputAsJson } = args;
|
|
45
|
+
const { projectConfig, projectDir } = await getProjectConfig();
|
|
46
|
+
try {
|
|
47
|
+
validateProjectConfig(projectConfig, projectDir);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
logError(error);
|
|
51
|
+
process.exit(EXIT_CODES.ERROR);
|
|
52
|
+
}
|
|
53
|
+
const projectName = projectConfig.name;
|
|
54
|
+
try {
|
|
55
|
+
if (formatOutputAsJson) {
|
|
56
|
+
const { data } = await listReleases(derivedAccountId, projectName, {
|
|
57
|
+
limit,
|
|
58
|
+
});
|
|
59
|
+
uiLogger.json(data);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
await fetchAndDisplayReleases(derivedAccountId, projectName, { limit });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
if (isPromptExitError(e)) {
|
|
67
|
+
throw e;
|
|
68
|
+
}
|
|
69
|
+
if (isHubSpotHttpError(e) && e.status === 404) {
|
|
70
|
+
uiLogger.error(commands.project.release.list.errors.projectNotFound(derivedAccountId, projectName));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
logError(e, new ApiErrorContext({
|
|
74
|
+
accountId: derivedAccountId,
|
|
75
|
+
request: 'project release list',
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
process.exit(EXIT_CODES.ERROR);
|
|
79
|
+
}
|
|
80
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
81
|
+
}
|
|
82
|
+
function projectReleaseListBuilder(yargs) {
|
|
83
|
+
yargs.options({
|
|
84
|
+
limit: {
|
|
85
|
+
describe: commands.project.release.list.options.limit,
|
|
86
|
+
type: 'number',
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
yargs.example([
|
|
90
|
+
['$0 project release list', commands.project.release.list.examples.default],
|
|
91
|
+
[
|
|
92
|
+
'$0 project release list --limit=5',
|
|
93
|
+
commands.project.release.list.examples.withLimit,
|
|
94
|
+
],
|
|
95
|
+
]);
|
|
96
|
+
return yargs;
|
|
97
|
+
}
|
|
98
|
+
const builder = makeYargsBuilder(projectReleaseListBuilder, command, verboseDescribe, {
|
|
99
|
+
useGlobalOptions: true,
|
|
100
|
+
useConfigOptions: true,
|
|
101
|
+
useAccountOptions: true,
|
|
102
|
+
useEnvironmentOptions: true,
|
|
103
|
+
useJSONOutputOptions: true,
|
|
104
|
+
});
|
|
105
|
+
const projectReleaseListCommand = {
|
|
106
|
+
command,
|
|
107
|
+
describe,
|
|
108
|
+
builder,
|
|
109
|
+
handler: makeWrappedYargsHandler('project-release-list', handler),
|
|
110
|
+
};
|
|
111
|
+
export default projectReleaseListCommand;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import create from './release/create.js';
|
|
2
|
+
import info from './release/info.js';
|
|
3
|
+
import list from './release/list.js';
|
|
4
|
+
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
5
|
+
// import { commands } from '../../lang/en.js';
|
|
6
|
+
const command = 'release';
|
|
7
|
+
// const describe = commands.project.release.describe;
|
|
8
|
+
const describe = undefined;
|
|
9
|
+
function projectReleaseBuilder(yargs) {
|
|
10
|
+
yargs.command(create).command(info).command(list).demandCommand(1, '');
|
|
11
|
+
return yargs;
|
|
12
|
+
}
|
|
13
|
+
const builder = makeYargsBuilder(projectReleaseBuilder, command, describe);
|
|
14
|
+
const projectReleaseCommand = {
|
|
15
|
+
command,
|
|
16
|
+
describe,
|
|
17
|
+
builder,
|
|
18
|
+
handler: () => { },
|
|
19
|
+
};
|
|
20
|
+
export default projectReleaseCommand;
|
|
@@ -6,7 +6,7 @@ import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { commands } from '../../lang/en.js';
|
|
8
8
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
9
|
-
import {
|
|
9
|
+
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
10
10
|
import { logError } from '../../lib/errorHandlers/index.js';
|
|
11
11
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
12
12
|
const command = 'update-deps [packages..]';
|
|
@@ -77,7 +77,7 @@ const builder = makeYargsBuilder(projectUpdateDepsBuilder, command, describe, {
|
|
|
77
77
|
const projectUpdateDepsCommand = {
|
|
78
78
|
command,
|
|
79
79
|
describe,
|
|
80
|
-
handler:
|
|
80
|
+
handler: makeWrappedYargsHandler('project-update-deps', handler),
|
|
81
81
|
builder,
|
|
82
82
|
};
|
|
83
83
|
export default projectUpdateDepsCommand;
|
|
@@ -4,7 +4,10 @@ export type ProjectUploadArgs = CommonArgs & JSONOutputArgs & {
|
|
|
4
4
|
message: string;
|
|
5
5
|
m: string;
|
|
6
6
|
skipValidation: boolean;
|
|
7
|
+
skipNpmAudit: boolean;
|
|
7
8
|
profile?: string;
|
|
9
|
+
preview: boolean;
|
|
10
|
+
target?: number;
|
|
8
11
|
};
|
|
9
12
|
declare const projectUploadCommand: YargsCommandModule<unknown, ProjectUploadArgs>;
|
|
10
13
|
export default projectUploadCommand;
|
|
@@ -8,17 +8,32 @@ import { logFeedbackMessage } from '../../lib/projects/ui.js';
|
|
|
8
8
|
import { handleProjectUpload } from '../../lib/projects/upload.js';
|
|
9
9
|
import { loadAndValidateProfile } from '../../lib/projects/projectProfiles.js';
|
|
10
10
|
import { displayWarnLogs, pollProjectBuildAndDeploy, } from '../../lib/projects/pollProjectBuildAndDeploy.js';
|
|
11
|
-
import {
|
|
11
|
+
import { triggerAndPollPreview } from '../../lib/projects/preview.js';
|
|
12
|
+
import { commands, lib } from '../../lang/en.js';
|
|
12
13
|
import { PROJECT_ERROR_TYPES } from '../../lib/constants.js';
|
|
13
14
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
14
15
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
15
|
-
import {
|
|
16
|
+
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
16
17
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
17
18
|
import { projectProfilePrompt } from '../../lib/prompts/projectProfilePrompt.js';
|
|
18
19
|
const command = 'upload';
|
|
19
20
|
const describe = commands.project.upload.describe;
|
|
21
|
+
async function handlePreview(accountId, projectId, buildId, targetPortalId) {
|
|
22
|
+
if (!projectId) {
|
|
23
|
+
uiLogger.warn(lib.projectPreview.missingProjectId);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const previewResult = await triggerAndPollPreview(accountId, projectId, buildId, targetPortalId);
|
|
27
|
+
if (!previewResult.succeeded) {
|
|
28
|
+
uiLogger.warn(lib.projectPreview.warning);
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
releaseTag: previewResult.releaseTag,
|
|
32
|
+
succeeded: previewResult.succeeded,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
20
35
|
async function handler(args) {
|
|
21
|
-
const { forceCreate, message, derivedAccountId, skipValidation, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, exit, addUsageMetadata, } = args;
|
|
36
|
+
const { forceCreate, message, derivedAccountId, skipValidation, skipNpmAudit, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, preview, target: targetPortalId, exit, addUsageMetadata, } = args;
|
|
22
37
|
const jsonOutput = {};
|
|
23
38
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
24
39
|
try {
|
|
@@ -56,16 +71,19 @@ async function handler(args) {
|
|
|
56
71
|
assetType: projectConfig.platformVersion,
|
|
57
72
|
});
|
|
58
73
|
try {
|
|
59
|
-
const { result, uploadError } = await handleProjectUpload({
|
|
74
|
+
const { result, uploadError, projectId } = await handleProjectUpload({
|
|
60
75
|
accountId: targetAccountId,
|
|
61
76
|
projectConfig,
|
|
62
77
|
projectDir,
|
|
63
|
-
callbackFunc:
|
|
78
|
+
callbackFunc: preview
|
|
79
|
+
? (...args) => pollProjectBuildAndDeploy(...args, { skipDeploy: true })
|
|
80
|
+
: pollProjectBuildAndDeploy,
|
|
64
81
|
uploadMessage: message,
|
|
65
82
|
forceCreate,
|
|
66
83
|
isUploadCommand: true,
|
|
67
84
|
sendIR: !isLegacyProject(projectConfig.platformVersion),
|
|
68
85
|
skipValidation,
|
|
86
|
+
skipNpmAudit,
|
|
69
87
|
profile: profileName,
|
|
70
88
|
});
|
|
71
89
|
if (uploadError) {
|
|
@@ -84,18 +102,37 @@ async function handler(args) {
|
|
|
84
102
|
}
|
|
85
103
|
return exit(EXIT_CODES.ERROR);
|
|
86
104
|
}
|
|
87
|
-
if (result &&
|
|
105
|
+
if (result &&
|
|
106
|
+
result.succeeded &&
|
|
107
|
+
(!result.buildResult.isAutoDeployEnabled || preview)) {
|
|
88
108
|
uiLogger.log(chalk.bold(commands.project.upload.logs.buildSucceeded(result.buildId)));
|
|
89
|
-
|
|
90
|
-
|
|
109
|
+
if (!preview) {
|
|
110
|
+
uiLogger.log(commands.project.upload.logs.autoDeployDisabled(`hs project deploy --build=${result.buildId}`));
|
|
111
|
+
logFeedbackMessage(result.buildId);
|
|
112
|
+
}
|
|
91
113
|
await displayWarnLogs(targetAccountId, projectConfig.name, result.buildId);
|
|
92
114
|
}
|
|
115
|
+
if (result && result.succeeded && preview && targetPortalId) {
|
|
116
|
+
const previewJson = await handlePreview(targetAccountId, projectId, result.buildId, targetPortalId);
|
|
117
|
+
if (previewJson && formatOutputAsJson) {
|
|
118
|
+
jsonOutput.preview = previewJson;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
93
121
|
if (result && result.succeeded && formatOutputAsJson) {
|
|
94
122
|
jsonOutput.buildId = result.buildId;
|
|
95
123
|
if (result.deployResult) {
|
|
96
124
|
jsonOutput.deployId = result.deployResult.deployId;
|
|
97
125
|
}
|
|
98
126
|
}
|
|
127
|
+
if (result && !result.succeeded) {
|
|
128
|
+
if (formatOutputAsJson) {
|
|
129
|
+
uiLogger.json(jsonOutput);
|
|
130
|
+
}
|
|
131
|
+
return exit(EXIT_CODES.ERROR);
|
|
132
|
+
}
|
|
133
|
+
if (!result && !uploadError) {
|
|
134
|
+
return exit(EXIT_CODES.ERROR);
|
|
135
|
+
}
|
|
99
136
|
}
|
|
100
137
|
catch (e) {
|
|
101
138
|
logError(e, new ApiErrorContext({
|
|
@@ -127,11 +164,37 @@ function projectUploadBuilder(yargs) {
|
|
|
127
164
|
hidden: true,
|
|
128
165
|
default: false,
|
|
129
166
|
},
|
|
167
|
+
'skip-npm-audit': {
|
|
168
|
+
describe: commands.project.upload.options.skipNpmAudit.describe,
|
|
169
|
+
type: 'boolean',
|
|
170
|
+
default: false,
|
|
171
|
+
},
|
|
130
172
|
profile: {
|
|
131
173
|
type: 'string',
|
|
132
174
|
alias: 'p',
|
|
133
175
|
describe: commands.project.upload.options.profile.describe,
|
|
134
176
|
},
|
|
177
|
+
preview: {
|
|
178
|
+
describe: commands.project.upload.options.preview.describe,
|
|
179
|
+
type: 'boolean',
|
|
180
|
+
default: false,
|
|
181
|
+
hidden: true,
|
|
182
|
+
},
|
|
183
|
+
target: {
|
|
184
|
+
describe: commands.project.upload.options.target.describe,
|
|
185
|
+
type: 'number',
|
|
186
|
+
requiresArg: true,
|
|
187
|
+
hidden: true,
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
yargs.check(argv => {
|
|
191
|
+
if (argv.preview && argv.target == null) {
|
|
192
|
+
throw new Error(commands.project.upload.errors.previewRequiresTarget);
|
|
193
|
+
}
|
|
194
|
+
if (argv.target != null && !argv.preview) {
|
|
195
|
+
throw new Error(commands.project.upload.errors.targetRequiresPreview);
|
|
196
|
+
}
|
|
197
|
+
return true;
|
|
135
198
|
});
|
|
136
199
|
yargs.conflicts('profile', 'account');
|
|
137
200
|
yargs.example([
|
|
@@ -140,6 +203,11 @@ function projectUploadBuilder(yargs) {
|
|
|
140
203
|
'$0 project upload --profile=profileName',
|
|
141
204
|
commands.project.upload.examples.withProfile,
|
|
142
205
|
],
|
|
206
|
+
// TODO: Unhide when 2026.09 ships
|
|
207
|
+
// [
|
|
208
|
+
// '$0 project upload --preview --target=12345',
|
|
209
|
+
// commands.project.upload.examples.withPreview,
|
|
210
|
+
// ],
|
|
143
211
|
]);
|
|
144
212
|
return yargs;
|
|
145
213
|
}
|
|
@@ -153,7 +221,7 @@ const builder = makeYargsBuilder(projectUploadBuilder, command, describe, {
|
|
|
153
221
|
const projectUploadCommand = {
|
|
154
222
|
command,
|
|
155
223
|
describe,
|
|
156
|
-
handler:
|
|
224
|
+
handler: makeWrappedYargsHandler('project-upload', handler),
|
|
157
225
|
builder,
|
|
158
226
|
};
|
|
159
227
|
export default projectUploadCommand;
|
|
@@ -4,7 +4,7 @@ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
|
4
4
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
5
5
|
import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
|
|
6
6
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
7
|
-
import {
|
|
7
|
+
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
8
8
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
9
9
|
import { validateSourceDirectory, handleTranslate, } from '../../lib/projects/upload.js';
|
|
10
10
|
import { commands } from '../../lang/en.js';
|
|
@@ -150,7 +150,7 @@ const builder = makeYargsBuilder(projectValidateBuilder, command, describe, {
|
|
|
150
150
|
const projectValidateCommand = {
|
|
151
151
|
command,
|
|
152
152
|
describe,
|
|
153
|
-
handler:
|
|
153
|
+
handler: makeWrappedYargsHandler('project-validate', handler),
|
|
154
154
|
builder,
|
|
155
155
|
};
|
|
156
156
|
export default projectValidateCommand;
|