@hubspot/cli 8.13.0 → 8.14.0-beta.1
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/cms/function/server.js +14 -7
- package/commands/project/dev/index.js +5 -0
- package/commands/project/dev/unifiedFlow.js +8 -0
- package/commands/project/listBuilds.d.ts +3 -2
- package/commands/project/listBuilds.js +37 -6
- package/commands/project/upload.js +5 -1
- package/commands/project/watch.js +3 -2
- package/lang/en.d.ts +17 -0
- package/lang/en.js +21 -2
- package/lib/cms/serverlessDevRuntime.d.ts +1 -0
- package/lib/cms/serverlessDevRuntime.js +72 -0
- package/lib/constants.d.ts +3 -0
- package/lib/constants.js +3 -0
- package/lib/jsonOutput.d.ts +73 -0
- package/lib/jsonOutput.js +64 -0
- package/lib/projects/create/v2.js +1 -0
- package/lib/projects/localDev/LocalDevLogger.d.ts +4 -0
- package/lib/projects/localDev/LocalDevLogger.js +18 -0
- package/lib/projects/localDev/LocalDevProcess.d.ts +11 -1
- package/lib/projects/localDev/LocalDevProcess.js +87 -5
- package/lib/projects/localDev/LocalDevState.d.ts +7 -1
- package/lib/projects/localDev/LocalDevState.js +19 -1
- package/lib/projects/localDev/LocalDevWatcher.js +1 -1
- package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +1 -0
- package/lib/projects/localDev/LocalDevWebsocketServer.js +23 -1
- package/lib/projects/localDev/localDevWebsocketServerUtils.d.ts +2 -1
- package/lib/projects/localDev/localDevWebsocketServerUtils.js +3 -0
- package/lib/projects/release.js +1 -1
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +1 -0
- package/mcp-server/tools/project/CreateProjectTool.d.ts +1 -0
- package/mcp-server/tools/project/constants.d.ts +1 -0
- package/mcp-server/tools/project/constants.js +2 -1
- package/package.json +12 -11
- package/types/LocalDev.d.ts +7 -0
- package/types/Yargs.d.ts +1 -0
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
2
|
-
// This package is not typed, so we need to use require
|
|
3
|
-
import { start as startTestServer } from '@hubspot/serverless-dev-runtime';
|
|
4
2
|
import { commands } from '../../../lang/en.js';
|
|
3
|
+
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
4
|
+
import { startServerlessDevRuntime } from '../../../lib/cms/serverlessDevRuntime.js';
|
|
5
|
+
import { logError } from '../../../lib/errorHandlers/index.js';
|
|
5
6
|
import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
|
|
6
7
|
import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
|
|
7
8
|
const command = 'server <path>';
|
|
8
9
|
const describe = undefined;
|
|
9
10
|
async function handler(args) {
|
|
10
|
-
const { path: functionPath, derivedAccountId } = args;
|
|
11
|
+
const { path: functionPath, derivedAccountId, exit } = args;
|
|
11
12
|
uiLogger.debug(commands.cms.subcommands.function.subcommands.server.debug.startingServer(functionPath));
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
try {
|
|
14
|
+
await startServerlessDevRuntime({
|
|
15
|
+
accountId: derivedAccountId,
|
|
16
|
+
...args,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
logError(e);
|
|
21
|
+
return exit(EXIT_CODES.ERROR);
|
|
22
|
+
}
|
|
16
23
|
}
|
|
17
24
|
function functionServerBuilder(yargs) {
|
|
18
25
|
yargs.positional('path', {
|
|
@@ -110,6 +110,11 @@ function projectDevBuilder(yargs) {
|
|
|
110
110
|
description: commands.project.dev.options.port,
|
|
111
111
|
default: LOCAL_DEV_DEFAULT_PORT,
|
|
112
112
|
});
|
|
113
|
+
yargs.option('auto-upload', {
|
|
114
|
+
type: 'boolean',
|
|
115
|
+
description: commands.project.dev.options.autoUpload,
|
|
116
|
+
default: false,
|
|
117
|
+
});
|
|
113
118
|
yargs.example([['$0 project dev', commands.project.dev.examples.default]]);
|
|
114
119
|
yargs.conflicts('profile', 'testing-account');
|
|
115
120
|
yargs.conflicts('profile', 'project-account');
|
|
@@ -155,6 +155,13 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
155
155
|
noLogs: true,
|
|
156
156
|
});
|
|
157
157
|
let project = uploadedProject;
|
|
158
|
+
// Fail fast before the slower project checks below.
|
|
159
|
+
const autoDeployEnabled = (project?.deployedBuild ?? project?.latestBuild)?.isAutoDeployEnabled ??
|
|
160
|
+
true;
|
|
161
|
+
if (args.autoUpload && !autoDeployEnabled) {
|
|
162
|
+
uiLogger.error(commands.project.dev.errors.autoUploadRequiresAutoDeploy);
|
|
163
|
+
return exit(EXIT_CODES.ERROR);
|
|
164
|
+
}
|
|
158
165
|
if (projectExists && project) {
|
|
159
166
|
await compareLocalProjectToDeployed(projectConfig, targetProjectAccountId, project.deployedBuild?.buildId, projectNodes, exit, args.profile);
|
|
160
167
|
}
|
|
@@ -189,6 +196,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
189
196
|
projectData: project,
|
|
190
197
|
env,
|
|
191
198
|
actions: { exit },
|
|
199
|
+
autoUploadEnabled: Boolean(args.autoUpload) && autoDeployEnabled,
|
|
192
200
|
});
|
|
193
201
|
const websocketServer = new LocalDevWebsocketServer(localDevProcess, args.debug);
|
|
194
202
|
const watcher = new LocalDevWatcher(localDevProcess);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
|
|
1
|
+
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
import { ProjectBuildsListJsonOutput } from '../../lib/jsonOutput.js';
|
|
3
|
+
export type ProjectListBuildsArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ProjectBuildsListJsonOutput> & {
|
|
3
4
|
project?: string;
|
|
4
5
|
limit?: number;
|
|
5
6
|
};
|
|
@@ -5,6 +5,7 @@ import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/con
|
|
|
5
5
|
import { getProjectDetailUrl } from '../../lib/projects/urls.js';
|
|
6
6
|
import moment from 'moment';
|
|
7
7
|
import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
8
|
+
import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
|
|
8
9
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
9
10
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
10
11
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
@@ -12,6 +13,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
|
12
13
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
13
14
|
import { commands } from '../../lang/en.js';
|
|
14
15
|
import { renderTable } from '../../ui/render.js';
|
|
16
|
+
import { ProjectBuildsListSchema, mapBuildToJsonOutput, } from '../../lib/jsonOutput.js';
|
|
15
17
|
const command = 'list-builds';
|
|
16
18
|
const describe = commands.project.listBuilds.describe;
|
|
17
19
|
async function fetchAndDisplayBuilds(accountId, project, options) {
|
|
@@ -40,7 +42,7 @@ async function fetchAndDisplayBuilds(accountId, project, options) {
|
|
|
40
42
|
});
|
|
41
43
|
renderTable(['Build ID', 'Status', 'Completed', 'Duration', 'Details'], builds);
|
|
42
44
|
}
|
|
43
|
-
if (options
|
|
45
|
+
if (options.after) {
|
|
44
46
|
if (results.length > 0) {
|
|
45
47
|
uiLogger.log(commands.project.listBuilds.showingNextBuilds(results.length, project.name));
|
|
46
48
|
}
|
|
@@ -48,7 +50,8 @@ async function fetchAndDisplayBuilds(accountId, project, options) {
|
|
|
48
50
|
else {
|
|
49
51
|
uiLogger.log(commands.project.listBuilds.showingRecentBuilds(results.length, project.name, uiLink(commands.project.listBuilds.viewAllBuildsLink, getProjectDetailUrl(project.name, accountId))));
|
|
50
52
|
}
|
|
51
|
-
|
|
53
|
+
const canPromptForMore = options.limit === undefined && Boolean(process.stdin.isTTY);
|
|
54
|
+
if (paging?.next?.after && canPromptForMore) {
|
|
52
55
|
await promptUser({
|
|
53
56
|
name: 'more',
|
|
54
57
|
message: commands.project.listBuilds.continueOrExitPrompt,
|
|
@@ -60,7 +63,7 @@ async function fetchAndDisplayBuilds(accountId, project, options) {
|
|
|
60
63
|
}
|
|
61
64
|
}
|
|
62
65
|
async function handler(args) {
|
|
63
|
-
const { project: projectFlagValue, limit, derivedAccountId, exit } = args;
|
|
66
|
+
const { project: projectFlagValue, limit, derivedAccountId, exit, json: formatOutputAsJson, addJsonOutput, } = args;
|
|
64
67
|
let projectName = projectFlagValue;
|
|
65
68
|
if (!projectName) {
|
|
66
69
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
@@ -78,9 +81,25 @@ async function handler(args) {
|
|
|
78
81
|
}
|
|
79
82
|
try {
|
|
80
83
|
const { data: project } = await fetchProject(derivedAccountId, projectName);
|
|
81
|
-
|
|
84
|
+
if (formatOutputAsJson) {
|
|
85
|
+
const { data: { results, paging }, } = await fetchProjectBuilds(derivedAccountId, project.name, { limit });
|
|
86
|
+
addJsonOutput({
|
|
87
|
+
projectName: project.name,
|
|
88
|
+
deployedBuildId: project.deployedBuildId,
|
|
89
|
+
results: results.map(build => mapBuildToJsonOutput(build, project.deployedBuildId)),
|
|
90
|
+
paging: paging?.next?.after
|
|
91
|
+
? { next: { after: paging.next.after } }
|
|
92
|
+
: undefined,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
await fetchAndDisplayBuilds(derivedAccountId, project, { limit });
|
|
97
|
+
}
|
|
82
98
|
}
|
|
83
99
|
catch (e) {
|
|
100
|
+
if (isPromptExitError(e)) {
|
|
101
|
+
return exit(e.exitCode);
|
|
102
|
+
}
|
|
84
103
|
if (isHubSpotHttpError(e) && e.status === 404) {
|
|
85
104
|
uiLogger.error(commands.project.listBuilds.errors.projectNotFound(projectName));
|
|
86
105
|
}
|
|
@@ -90,6 +109,7 @@ async function handler(args) {
|
|
|
90
109
|
projectName,
|
|
91
110
|
}));
|
|
92
111
|
}
|
|
112
|
+
return exit(EXIT_CODES.ERROR);
|
|
93
113
|
}
|
|
94
114
|
return exit(EXIT_CODES.SUCCESS);
|
|
95
115
|
}
|
|
@@ -101,11 +121,19 @@ function projectListBuildsBuilder(yargs) {
|
|
|
101
121
|
},
|
|
102
122
|
limit: {
|
|
103
123
|
describe: commands.project.listBuilds.options.limit.describe,
|
|
104
|
-
type: '
|
|
124
|
+
type: 'number',
|
|
105
125
|
},
|
|
106
126
|
});
|
|
107
127
|
yargs.example([
|
|
108
128
|
['$0 project list-builds', commands.project.listBuilds.examples.default],
|
|
129
|
+
[
|
|
130
|
+
'$0 project list-builds --limit=5',
|
|
131
|
+
commands.project.listBuilds.examples.withLimit,
|
|
132
|
+
],
|
|
133
|
+
[
|
|
134
|
+
'$0 project list-builds --json',
|
|
135
|
+
commands.project.listBuilds.examples.json,
|
|
136
|
+
],
|
|
109
137
|
]);
|
|
110
138
|
return yargs;
|
|
111
139
|
}
|
|
@@ -114,11 +142,14 @@ const builder = makeYargsBuilder(projectListBuildsBuilder, command, describe, {
|
|
|
114
142
|
useConfigOptions: true,
|
|
115
143
|
useAccountOptions: true,
|
|
116
144
|
useEnvironmentOptions: true,
|
|
145
|
+
useJSONOutputOptions: true,
|
|
117
146
|
});
|
|
118
147
|
const projectListBuildsCommand = {
|
|
119
148
|
command,
|
|
120
149
|
describe,
|
|
121
|
-
handler: makeWrappedYargsHandler('project-list-builds', handler
|
|
150
|
+
handler: makeWrappedYargsHandler('project-list-builds', handler, {
|
|
151
|
+
jsonOutputSchema: ProjectBuildsListSchema,
|
|
152
|
+
}),
|
|
122
153
|
builder,
|
|
123
154
|
};
|
|
124
155
|
export default projectListBuildsCommand;
|
|
@@ -17,6 +17,7 @@ import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler
|
|
|
17
17
|
import { UploadSchema, } from '../../lib/jsonOutput.js';
|
|
18
18
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
19
19
|
import { projectProfilePrompt } from '../../lib/prompts/projectProfilePrompt.js';
|
|
20
|
+
import { uiDeprecatedTag } from '../../lib/ui/index.js';
|
|
20
21
|
import { showMcpPromotionNudge } from '../../lib/mcp/promotion.js';
|
|
21
22
|
import { PLATFORM_VERSIONS } from '@hubspot/project-parsing-lib/constants';
|
|
22
23
|
const command = 'upload';
|
|
@@ -37,6 +38,9 @@ async function handlePreview(accountId, projectId, buildId, targetPortalId) {
|
|
|
37
38
|
}
|
|
38
39
|
async function handler(args) {
|
|
39
40
|
const { force = false, forceCreate = false, message, derivedAccountId, skipValidation, skipNpmAudit, skipAutoDeploy, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, preview, target: targetPortalId, exit, addUsageMetadata, addJsonOutput, } = args;
|
|
41
|
+
if (forceCreate) {
|
|
42
|
+
uiDeprecatedTag(commands.project.upload.logs.forceCreateDeprecated);
|
|
43
|
+
}
|
|
40
44
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
41
45
|
try {
|
|
42
46
|
validateProjectConfig(projectConfig, projectDir);
|
|
@@ -114,7 +118,7 @@ async function handler(args) {
|
|
|
114
118
|
(!result.buildResult.isAutoDeployEnabled || preview || skipAutoDeploy)) {
|
|
115
119
|
uiLogger.log(chalk.bold(commands.project.upload.logs.buildSucceeded(result.buildId)));
|
|
116
120
|
if (!preview) {
|
|
117
|
-
if (meetsMinimumPlatformVersion(result.buildResult.platformVersion, PLATFORM_VERSIONS.
|
|
121
|
+
if (meetsMinimumPlatformVersion(result.buildResult.platformVersion, PLATFORM_VERSIONS.v2027_03_BETA)) {
|
|
118
122
|
const releaseCommand = `hs project release create --build=${result.buildId}`;
|
|
119
123
|
uiLogger.log(commands.project.upload.logs.releaseManagementRequired(releaseCommand));
|
|
120
124
|
}
|
|
@@ -14,9 +14,9 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
|
14
14
|
import { handleKeypress, handleExit } from '../../lib/process.js';
|
|
15
15
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
16
16
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
17
|
-
import {
|
|
17
|
+
import { uiCommandRelocatedMessage, uiCommandRenamedDescription, } from '../../lib/ui/index.js';
|
|
18
18
|
const command = 'watch';
|
|
19
|
-
const describe =
|
|
19
|
+
const describe = uiCommandRenamedDescription(commands.project.watch.describe, 'hs project dev');
|
|
20
20
|
async function handleBuildStatus(accountId, projectName, buildId) {
|
|
21
21
|
const { isAutoDeployEnabled, deployStatusTaskLocator } = await pollBuildStatus(accountId, projectName, buildId, null);
|
|
22
22
|
if (isAutoDeployEnabled && deployStatusTaskLocator) {
|
|
@@ -57,6 +57,7 @@ function handleUserInput(accountId, projectName, currentBuildId, exit) {
|
|
|
57
57
|
}
|
|
58
58
|
async function handler(args) {
|
|
59
59
|
const { initialUpload, derivedAccountId, exit } = args;
|
|
60
|
+
uiCommandRelocatedMessage('hs project dev');
|
|
60
61
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
61
62
|
if (!projectConfig || !projectDir) {
|
|
62
63
|
uiLogger.error(commands.project.watch.errors.projectConfigNotFound);
|
package/lang/en.d.ts
CHANGED
|
@@ -1529,6 +1529,7 @@ export declare const commands: {
|
|
|
1529
1529
|
noRunnableComponents: string;
|
|
1530
1530
|
accountNotCombined: string;
|
|
1531
1531
|
localDevAlreadyRunning: string;
|
|
1532
|
+
autoUploadRequiresAutoDeploy: string;
|
|
1532
1533
|
};
|
|
1533
1534
|
examples: {
|
|
1534
1535
|
default: string;
|
|
@@ -1541,6 +1542,7 @@ export declare const commands: {
|
|
|
1541
1542
|
projectAccount: string;
|
|
1542
1543
|
testingAccount: string;
|
|
1543
1544
|
port: string;
|
|
1545
|
+
autoUpload: string;
|
|
1544
1546
|
};
|
|
1545
1547
|
};
|
|
1546
1548
|
create: {
|
|
@@ -1842,6 +1844,8 @@ export declare const commands: {
|
|
|
1842
1844
|
};
|
|
1843
1845
|
examples: {
|
|
1844
1846
|
default: string;
|
|
1847
|
+
withLimit: string;
|
|
1848
|
+
json: string;
|
|
1845
1849
|
};
|
|
1846
1850
|
};
|
|
1847
1851
|
logs: {
|
|
@@ -1901,6 +1905,7 @@ export declare const commands: {
|
|
|
1901
1905
|
withPreview: string;
|
|
1902
1906
|
};
|
|
1903
1907
|
logs: {
|
|
1908
|
+
forceCreateDeprecated: string;
|
|
1904
1909
|
buildSucceeded: (buildId: number) => string;
|
|
1905
1910
|
readyToGoLive: string;
|
|
1906
1911
|
runCommand: (command: string) => string;
|
|
@@ -3375,6 +3380,7 @@ export declare const lib: {
|
|
|
3375
3380
|
learnMoreLocalDevServer: string;
|
|
3376
3381
|
running: (projectName: string, accountIdentifier: string) => string;
|
|
3377
3382
|
quitHelper: string;
|
|
3383
|
+
autoUploadEnabled: string;
|
|
3378
3384
|
viewProjectLink: (name: string, accountId: number) => string;
|
|
3379
3385
|
viewLocalDevUILink: (accountId: number, showWelcomeScreen: boolean) => string;
|
|
3380
3386
|
localDevUIAutoMessage: (accountId: number, showWelcomeScreen: boolean) => string;
|
|
@@ -3466,6 +3472,10 @@ export declare const lib: {
|
|
|
3466
3472
|
LocalDevProcess: {
|
|
3467
3473
|
projectConfigMismatch: string;
|
|
3468
3474
|
uploadInitiated: string;
|
|
3475
|
+
autoUploadScheduled: (filePath: string) => string;
|
|
3476
|
+
autoUploadTriggered: string;
|
|
3477
|
+
autoUploadInProgress: string;
|
|
3478
|
+
autoUploadToggled: (enabled: boolean) => string;
|
|
3469
3479
|
deployInitiated: string;
|
|
3470
3480
|
uploadFailed: string;
|
|
3471
3481
|
deployFailed: string;
|
|
@@ -4494,6 +4504,13 @@ export declare const lib: {
|
|
|
4494
4504
|
copyingProjectFilesFailed: string;
|
|
4495
4505
|
};
|
|
4496
4506
|
};
|
|
4507
|
+
cms: {
|
|
4508
|
+
serverlessDevRuntime: {
|
|
4509
|
+
installStarted: (targetVersion: string) => string;
|
|
4510
|
+
installSucceeded: string;
|
|
4511
|
+
installFailed: string;
|
|
4512
|
+
};
|
|
4513
|
+
};
|
|
4497
4514
|
theme: {
|
|
4498
4515
|
cmsDevServerProcess: {
|
|
4499
4516
|
installStarted: (targetVersion: string) => string;
|
package/lang/en.js
CHANGED
|
@@ -1545,6 +1545,7 @@ export const commands = {
|
|
|
1545
1545
|
noRunnableComponents: `No supported components were found in this project. Run ${uiCommandReference('hs project add')} to see a list of available components and add one to your project.`,
|
|
1546
1546
|
accountNotCombined: `\nLocal development of unified apps is currently only compatible with accounts that are opted into the unified apps beta. Make sure that this account is opted in or switch accounts using ${uiCommandReference('hs account use')}.`,
|
|
1547
1547
|
localDevAlreadyRunning: `Another ${uiCommandReference('hs project dev')} process is already running. To proceed with local development of this project, stop the existing process and re-run ${uiCommandReference('hs project dev')}.`,
|
|
1548
|
+
autoUploadRequiresAutoDeploy: `${uiCommandReference('hs project dev --auto-upload')} requires auto-deploy to be enabled for this project, since auto-upload deploys every change. Enable auto-deploy in your project settings, or run ${uiCommandReference('hs project dev')} without it.`,
|
|
1548
1549
|
},
|
|
1549
1550
|
examples: {
|
|
1550
1551
|
default: 'Start local dev for the current project',
|
|
@@ -1557,6 +1558,7 @@ export const commands = {
|
|
|
1557
1558
|
projectAccount: 'The id of the account to upload your project to. Must be used with --testing-account.',
|
|
1558
1559
|
testingAccount: 'The id of the account to install apps and test on. Must be used with --project-account.',
|
|
1559
1560
|
port: `The port for the local dev server. Defaults to ${LOCAL_DEV_DEFAULT_PORT}.`,
|
|
1561
|
+
autoUpload: 'Automatically upload local changes to HubSpot as you edit files, instead of uploading manually from the Local Dev Panel.',
|
|
1560
1562
|
},
|
|
1561
1563
|
},
|
|
1562
1564
|
create: {
|
|
@@ -1858,6 +1860,8 @@ export const commands = {
|
|
|
1858
1860
|
},
|
|
1859
1861
|
examples: {
|
|
1860
1862
|
default: 'List the builds for the current project',
|
|
1863
|
+
withLimit: 'List the five most recent builds for the current project',
|
|
1864
|
+
json: 'Output the builds for the current project as JSON',
|
|
1861
1865
|
},
|
|
1862
1866
|
},
|
|
1863
1867
|
logs: {
|
|
@@ -1917,6 +1921,7 @@ export const commands = {
|
|
|
1917
1921
|
withPreview: 'Upload and preview the build on a target portal',
|
|
1918
1922
|
},
|
|
1919
1923
|
logs: {
|
|
1924
|
+
forceCreateDeprecated: `The ${uiCommandReference('--force-create')} flag is deprecated. Use ${uiCommandReference('--force')} instead.`,
|
|
1920
1925
|
buildSucceeded: (buildId) => `Build #${buildId} succeeded\n`,
|
|
1921
1926
|
readyToGoLive: '🚀 Ready to take your project live?',
|
|
1922
1927
|
runCommand: (command) => `Run \`${uiCommandReference(command)}\``,
|
|
@@ -3400,6 +3405,7 @@ export const lib = {
|
|
|
3400
3405
|
learnMoreLocalDevServer: uiLink('Learn more about the projects local dev server', 'https://developers.hubspot.com/docs/developer-tooling/local-development/hubspot-cli/project-commands'),
|
|
3401
3406
|
running: (projectName, accountIdentifier) => chalk.hex(UI_COLORS.SORBET)(`Running ${chalk.bold(projectName)} locally on ${accountIdentifier}, waiting for changes ...`),
|
|
3402
3407
|
quitHelper: `Press ${chalk.bold('q')} to stop the local dev server`,
|
|
3408
|
+
autoUploadEnabled: `${chalk.bold('Auto-upload is on.')} Changes you make locally will be uploaded to HubSpot automatically.`,
|
|
3403
3409
|
viewProjectLink: (name, accountId) => uiLink('View project in HubSpot', getProjectDetailUrl(name, accountId) || ''),
|
|
3404
3410
|
viewLocalDevUILink: (accountId, showWelcomeScreen) => uiLink('View local dev session in HubSpot', getLocalDevUiUrl(accountId, showWelcomeScreen)),
|
|
3405
3411
|
localDevUIAutoMessage: (accountId, showWelcomeScreen) => `Opening your ${uiLink('local dev session in HubSpot', getLocalDevUiUrl(accountId, showWelcomeScreen))}...`,
|
|
@@ -3490,8 +3496,14 @@ export const lib = {
|
|
|
3490
3496
|
},
|
|
3491
3497
|
LocalDevProcess: {
|
|
3492
3498
|
projectConfigMismatch: `Unable to upload project. The project config has been modified since starting ${uiCommandReference('hs project dev')}.`,
|
|
3493
|
-
uploadInitiated: 'Project upload initiated
|
|
3494
|
-
|
|
3499
|
+
uploadInitiated: 'Project upload initiated.',
|
|
3500
|
+
autoUploadScheduled: (filePath) => `Auto-upload: detected change to ${filePath}, upload scheduled.`,
|
|
3501
|
+
autoUploadTriggered: 'Auto-upload: debounce elapsed, uploading now.',
|
|
3502
|
+
autoUploadInProgress: 'Auto-upload: an upload is already running, will re-run after it finishes.',
|
|
3503
|
+
autoUploadToggled: (enabled) => enabled
|
|
3504
|
+
? `${chalk.bold('Auto-upload turned on')} from the Local Dev Panel. Changes you make locally will be uploaded to HubSpot automatically.`
|
|
3505
|
+
: `${chalk.bold('Auto-upload turned off')} from the Local Dev Panel. Upload manually from the Local Dev Panel to push your changes.`,
|
|
3506
|
+
deployInitiated: 'Project deploy initiated from the Local Dev Panel.',
|
|
3495
3507
|
uploadFailed: 'Project upload failed. To proceed with local development, fix any necessary errors, then re-upload your project.',
|
|
3496
3508
|
deployFailed: 'Project deploy failed. To proceed with local development, fix any necessary errors, then re-deploy your project.',
|
|
3497
3509
|
uploadSuccess: 'Project upload completed successfully. Resuming local dev...',
|
|
@@ -4531,6 +4543,13 @@ export const lib = {
|
|
|
4531
4543
|
copyingProjectFilesFailed: 'Unable to copy migrated project files',
|
|
4532
4544
|
},
|
|
4533
4545
|
},
|
|
4546
|
+
cms: {
|
|
4547
|
+
serverlessDevRuntime: {
|
|
4548
|
+
installStarted: (targetVersion) => `Installing serverless-dev-runtime ${targetVersion}...`,
|
|
4549
|
+
installSucceeded: 'serverless-dev-runtime setup complete',
|
|
4550
|
+
installFailed: 'Failed to install serverless-dev-runtime',
|
|
4551
|
+
},
|
|
4552
|
+
},
|
|
4534
4553
|
theme: {
|
|
4535
4554
|
cmsDevServerProcess: {
|
|
4536
4555
|
installStarted: (targetVersion) => `Installing cms-dev-server ${targetVersion}...`,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function startServerlessDevRuntime(options: any): Promise<void>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
import SpinniesManager from '../ui/SpinniesManager.js';
|
|
7
|
+
import { lib } from '../../lang/en.js';
|
|
8
|
+
const TARGET_SERVERLESS_RUNTIME_VERSION = '7.0.7';
|
|
9
|
+
const CACHE_DIR = path.join(os.homedir(), '.hscli', '.serverless-runtime-cache');
|
|
10
|
+
async function ensureServerlessRuntimeInstalled() {
|
|
11
|
+
const packageJsonPath = path.join(CACHE_DIR, 'node_modules', '@hubspot', 'serverless-dev-runtime', 'package.json');
|
|
12
|
+
let needsInstall = true;
|
|
13
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
14
|
+
try {
|
|
15
|
+
const installed = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
16
|
+
if (installed.version === TARGET_SERVERLESS_RUNTIME_VERSION) {
|
|
17
|
+
needsInstall = false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
needsInstall = true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!needsInstall) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
SpinniesManager.init({ succeedColor: 'white' });
|
|
28
|
+
SpinniesManager.add('serverless-runtime-install', {
|
|
29
|
+
text: lib.cms.serverlessDevRuntime.installStarted(TARGET_SERVERLESS_RUNTIME_VERSION),
|
|
30
|
+
});
|
|
31
|
+
fs.mkdirSync(CACHE_DIR, { recursive: true });
|
|
32
|
+
const nodeModulesDir = path.join(CACHE_DIR, 'node_modules');
|
|
33
|
+
if (fs.existsSync(nodeModulesDir)) {
|
|
34
|
+
fs.rmSync(nodeModulesDir, { recursive: true, force: true });
|
|
35
|
+
}
|
|
36
|
+
await new Promise((resolve, reject) => {
|
|
37
|
+
const installProcess = spawn('npm', [
|
|
38
|
+
'install',
|
|
39
|
+
`@hubspot/serverless-dev-runtime@${TARGET_SERVERLESS_RUNTIME_VERSION}`,
|
|
40
|
+
'--production',
|
|
41
|
+
'--no-save',
|
|
42
|
+
'--loglevel=error',
|
|
43
|
+
], { cwd: CACHE_DIR, stdio: 'ignore' });
|
|
44
|
+
installProcess.on('close', code => {
|
|
45
|
+
if (code === 0) {
|
|
46
|
+
SpinniesManager.succeed('serverless-runtime-install', {
|
|
47
|
+
text: lib.cms.serverlessDevRuntime.installSucceeded,
|
|
48
|
+
});
|
|
49
|
+
resolve();
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
SpinniesManager.fail('serverless-runtime-install', {
|
|
53
|
+
text: lib.cms.serverlessDevRuntime.installFailed,
|
|
54
|
+
});
|
|
55
|
+
reject(new Error(lib.cms.serverlessDevRuntime.installFailed));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
installProcess.on('error', error => {
|
|
59
|
+
SpinniesManager.fail('serverless-runtime-install', {
|
|
60
|
+
text: lib.cms.serverlessDevRuntime.installFailed,
|
|
61
|
+
});
|
|
62
|
+
reject(error);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
67
|
+
export async function startServerlessDevRuntime(options) {
|
|
68
|
+
await ensureServerlessRuntimeInstalled();
|
|
69
|
+
const requireFromCache = createRequire(path.join(CACHE_DIR, 'package.json'));
|
|
70
|
+
const { start } = requireFromCache('@hubspot/serverless-dev-runtime');
|
|
71
|
+
start(options);
|
|
72
|
+
}
|
package/lib/constants.d.ts
CHANGED
|
@@ -82,6 +82,7 @@ export declare const FEATURES: {
|
|
|
82
82
|
readonly APP_EVENTS: "Developers:UnifiedApps:AppEventsAccess";
|
|
83
83
|
readonly THEME_MIGRATION_2025_2: "Developers:ProjectThemeMigrations:2025.2";
|
|
84
84
|
readonly AGENT_TOOLS: "ThirdPartyAgentTools";
|
|
85
|
+
readonly APP_ACTIONS: "Developers:AppActions";
|
|
85
86
|
};
|
|
86
87
|
export declare const LOCAL_DEV_UI_MESSAGE_SEND_TYPES: {
|
|
87
88
|
UPLOAD_SUCCESS: string;
|
|
@@ -93,6 +94,7 @@ export declare const LOCAL_DEV_UI_MESSAGE_SEND_TYPES: {
|
|
|
93
94
|
UPDATE_PROJECT_DATA: string;
|
|
94
95
|
UPDATE_UPLOAD_WARNINGS: string;
|
|
95
96
|
DEV_SERVERS_STARTED: string;
|
|
97
|
+
UPLOAD_IN_PROGRESS: string;
|
|
96
98
|
};
|
|
97
99
|
export declare const LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES: {
|
|
98
100
|
UPLOAD: string;
|
|
@@ -101,6 +103,7 @@ export declare const LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES: {
|
|
|
101
103
|
APP_INSTALL_SUCCESS: string;
|
|
102
104
|
APP_INSTALL_INITIATED: string;
|
|
103
105
|
APP_INSTALL_FAILURE: string;
|
|
106
|
+
SET_AUTO_UPLOAD: string;
|
|
104
107
|
};
|
|
105
108
|
export declare const APP_INSTALLATION_STATES: {
|
|
106
109
|
readonly NOT_INSTALLED: "NOT_INSTALLED";
|
package/lib/constants.js
CHANGED
|
@@ -74,6 +74,7 @@ export const FEATURES = {
|
|
|
74
74
|
APP_EVENTS: 'Developers:UnifiedApps:AppEventsAccess',
|
|
75
75
|
THEME_MIGRATION_2025_2: 'Developers:ProjectThemeMigrations:2025.2',
|
|
76
76
|
AGENT_TOOLS: 'ThirdPartyAgentTools',
|
|
77
|
+
APP_ACTIONS: 'Developers:AppActions',
|
|
77
78
|
};
|
|
78
79
|
export const LOCAL_DEV_UI_MESSAGE_SEND_TYPES = {
|
|
79
80
|
UPLOAD_SUCCESS: 'server:uploadSuccess',
|
|
@@ -85,6 +86,7 @@ export const LOCAL_DEV_UI_MESSAGE_SEND_TYPES = {
|
|
|
85
86
|
UPDATE_PROJECT_DATA: 'server:updateProjectData',
|
|
86
87
|
UPDATE_UPLOAD_WARNINGS: 'server:updateUploadWarnings',
|
|
87
88
|
DEV_SERVERS_STARTED: 'server:devServersStarted',
|
|
89
|
+
UPLOAD_IN_PROGRESS: 'server:uploadInProgress',
|
|
88
90
|
};
|
|
89
91
|
export const LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES = {
|
|
90
92
|
UPLOAD: 'client:upload',
|
|
@@ -93,6 +95,7 @@ export const LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES = {
|
|
|
93
95
|
APP_INSTALL_SUCCESS: 'client:installSuccess',
|
|
94
96
|
APP_INSTALL_INITIATED: 'client:installInitiated',
|
|
95
97
|
APP_INSTALL_FAILURE: 'client:installFailure',
|
|
98
|
+
SET_AUTO_UPLOAD: 'client:setAutoUpload',
|
|
96
99
|
};
|
|
97
100
|
export const APP_INSTALLATION_STATES = {
|
|
98
101
|
NOT_INSTALLED: 'NOT_INSTALLED',
|
package/lib/jsonOutput.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { Build } from '@hubspot/local-dev-lib/types/Build';
|
|
2
3
|
import { Release } from '../api/releases.js';
|
|
3
4
|
declare const ReleaseComponentSchema: z.ZodObject<{
|
|
4
5
|
buildType: z.ZodString;
|
|
@@ -35,6 +36,74 @@ export declare const ReleaseListSchema: z.ZodObject<{
|
|
|
35
36
|
}, z.core.$strip>;
|
|
36
37
|
}, z.core.$strip>>;
|
|
37
38
|
}, z.core.$strip>;
|
|
39
|
+
declare const BuildSubbuildStatusSchema: z.ZodObject<{
|
|
40
|
+
buildName: z.ZodString;
|
|
41
|
+
buildType: z.ZodString;
|
|
42
|
+
status: z.ZodString;
|
|
43
|
+
errorMessage: z.ZodOptional<z.ZodString>;
|
|
44
|
+
startedAt: z.ZodOptional<z.ZodString>;
|
|
45
|
+
finishedAt: z.ZodOptional<z.ZodString>;
|
|
46
|
+
rootPath: z.ZodOptional<z.ZodString>;
|
|
47
|
+
id: z.ZodOptional<z.ZodString>;
|
|
48
|
+
visible: z.ZodOptional<z.ZodBoolean>;
|
|
49
|
+
}, z.core.$strip>;
|
|
50
|
+
export declare const BuildSchema: z.ZodObject<{
|
|
51
|
+
buildId: z.ZodNumber;
|
|
52
|
+
status: z.ZodString;
|
|
53
|
+
isDeployed: z.ZodBoolean;
|
|
54
|
+
isAutoDeployEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
55
|
+
deployableState: z.ZodOptional<z.ZodString>;
|
|
56
|
+
platformVersion: z.ZodOptional<z.ZodString>;
|
|
57
|
+
uploadMessage: z.ZodOptional<z.ZodString>;
|
|
58
|
+
enqueuedAt: z.ZodOptional<z.ZodString>;
|
|
59
|
+
startedAt: z.ZodOptional<z.ZodString>;
|
|
60
|
+
finishedAt: z.ZodOptional<z.ZodString>;
|
|
61
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
62
|
+
subbuildStatuses: z.ZodArray<z.ZodObject<{
|
|
63
|
+
buildName: z.ZodString;
|
|
64
|
+
buildType: z.ZodString;
|
|
65
|
+
status: z.ZodString;
|
|
66
|
+
errorMessage: z.ZodOptional<z.ZodString>;
|
|
67
|
+
startedAt: z.ZodOptional<z.ZodString>;
|
|
68
|
+
finishedAt: z.ZodOptional<z.ZodString>;
|
|
69
|
+
rootPath: z.ZodOptional<z.ZodString>;
|
|
70
|
+
id: z.ZodOptional<z.ZodString>;
|
|
71
|
+
visible: z.ZodOptional<z.ZodBoolean>;
|
|
72
|
+
}, z.core.$strip>>;
|
|
73
|
+
}, z.core.$strip>;
|
|
74
|
+
export declare const ProjectBuildsListSchema: z.ZodObject<{
|
|
75
|
+
projectName: z.ZodString;
|
|
76
|
+
deployedBuildId: z.ZodOptional<z.ZodNumber>;
|
|
77
|
+
results: z.ZodArray<z.ZodObject<{
|
|
78
|
+
buildId: z.ZodNumber;
|
|
79
|
+
status: z.ZodString;
|
|
80
|
+
isDeployed: z.ZodBoolean;
|
|
81
|
+
isAutoDeployEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
82
|
+
deployableState: z.ZodOptional<z.ZodString>;
|
|
83
|
+
platformVersion: z.ZodOptional<z.ZodString>;
|
|
84
|
+
uploadMessage: z.ZodOptional<z.ZodString>;
|
|
85
|
+
enqueuedAt: z.ZodOptional<z.ZodString>;
|
|
86
|
+
startedAt: z.ZodOptional<z.ZodString>;
|
|
87
|
+
finishedAt: z.ZodOptional<z.ZodString>;
|
|
88
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
89
|
+
subbuildStatuses: z.ZodArray<z.ZodObject<{
|
|
90
|
+
buildName: z.ZodString;
|
|
91
|
+
buildType: z.ZodString;
|
|
92
|
+
status: z.ZodString;
|
|
93
|
+
errorMessage: z.ZodOptional<z.ZodString>;
|
|
94
|
+
startedAt: z.ZodOptional<z.ZodString>;
|
|
95
|
+
finishedAt: z.ZodOptional<z.ZodString>;
|
|
96
|
+
rootPath: z.ZodOptional<z.ZodString>;
|
|
97
|
+
id: z.ZodOptional<z.ZodString>;
|
|
98
|
+
visible: z.ZodOptional<z.ZodBoolean>;
|
|
99
|
+
}, z.core.$strip>>;
|
|
100
|
+
}, z.core.$strip>>;
|
|
101
|
+
paging: z.ZodOptional<z.ZodObject<{
|
|
102
|
+
next: z.ZodObject<{
|
|
103
|
+
after: z.ZodString;
|
|
104
|
+
}, z.core.$strip>;
|
|
105
|
+
}, z.core.$strip>>;
|
|
106
|
+
}, z.core.$strip>;
|
|
38
107
|
export declare const ProjectInfoSchema: z.ZodObject<{
|
|
39
108
|
projectName: z.ZodString;
|
|
40
109
|
platformVersion: z.ZodString;
|
|
@@ -98,6 +167,9 @@ export declare const CreateTestAccountSchema: z.ZodObject<{
|
|
|
98
167
|
export type ReleaseComponentJsonOutput = z.infer<typeof ReleaseComponentSchema>;
|
|
99
168
|
export type ReleaseJsonOutput = z.infer<typeof ReleaseSchema>;
|
|
100
169
|
export type ReleaseListJsonOutput = z.infer<typeof ReleaseListSchema>;
|
|
170
|
+
export type BuildSubbuildStatusJsonOutput = z.infer<typeof BuildSubbuildStatusSchema>;
|
|
171
|
+
export type BuildJsonOutput = z.infer<typeof BuildSchema>;
|
|
172
|
+
export type ProjectBuildsListJsonOutput = z.infer<typeof ProjectBuildsListSchema>;
|
|
101
173
|
export type ProjectInfoJsonOutput = z.infer<typeof ProjectInfoSchema>;
|
|
102
174
|
export type PreviewJsonOutput = z.infer<typeof PreviewSchema>;
|
|
103
175
|
export type UploadJsonOutput = z.infer<typeof UploadSchema>;
|
|
@@ -105,5 +177,6 @@ export type DeployJsonOutput = z.infer<typeof DeploySchema>;
|
|
|
105
177
|
export type InstallStatusJsonOutput = z.infer<typeof InstallStatusSchema>;
|
|
106
178
|
export type InstallAppJsonOutput = z.infer<typeof InstallAppSchema>;
|
|
107
179
|
export type CreateTestAccountJsonOutput = z.infer<typeof CreateTestAccountSchema>;
|
|
180
|
+
export declare function mapBuildToJsonOutput(build: Build, deployedBuildId?: number): BuildJsonOutput;
|
|
108
181
|
export declare function mapReleaseToJsonOutput(release: Release): ReleaseJsonOutput;
|
|
109
182
|
export {};
|
package/lib/jsonOutput.js
CHANGED
|
@@ -21,6 +21,43 @@ export const ReleaseListSchema = z.object({
|
|
|
21
21
|
})
|
|
22
22
|
.optional(),
|
|
23
23
|
});
|
|
24
|
+
const BuildSubbuildStatusSchema = z.object({
|
|
25
|
+
buildName: z.string(),
|
|
26
|
+
buildType: z.string(),
|
|
27
|
+
status: z.string(),
|
|
28
|
+
errorMessage: z.string().optional(),
|
|
29
|
+
startedAt: z.string().optional(),
|
|
30
|
+
finishedAt: z.string().optional(),
|
|
31
|
+
rootPath: z.string().optional(),
|
|
32
|
+
id: z.string().optional(),
|
|
33
|
+
visible: z.boolean().optional(),
|
|
34
|
+
});
|
|
35
|
+
export const BuildSchema = z.object({
|
|
36
|
+
buildId: z.number(),
|
|
37
|
+
status: z.string(),
|
|
38
|
+
isDeployed: z.boolean(),
|
|
39
|
+
isAutoDeployEnabled: z.boolean().optional(),
|
|
40
|
+
deployableState: z.string().optional(),
|
|
41
|
+
platformVersion: z.string().optional(),
|
|
42
|
+
uploadMessage: z.string().optional(),
|
|
43
|
+
enqueuedAt: z.string().optional(),
|
|
44
|
+
startedAt: z.string().optional(),
|
|
45
|
+
finishedAt: z.string().optional(),
|
|
46
|
+
createdAt: z.string().optional(),
|
|
47
|
+
subbuildStatuses: z.array(BuildSubbuildStatusSchema),
|
|
48
|
+
});
|
|
49
|
+
export const ProjectBuildsListSchema = z.object({
|
|
50
|
+
projectName: z.string(),
|
|
51
|
+
deployedBuildId: z.number().optional(),
|
|
52
|
+
results: z.array(BuildSchema),
|
|
53
|
+
paging: z
|
|
54
|
+
.object({
|
|
55
|
+
next: z.object({
|
|
56
|
+
after: z.string(),
|
|
57
|
+
}),
|
|
58
|
+
})
|
|
59
|
+
.optional(),
|
|
60
|
+
});
|
|
24
61
|
export const ProjectInfoSchema = z.object({
|
|
25
62
|
projectName: z.string(),
|
|
26
63
|
platformVersion: z.string(),
|
|
@@ -78,6 +115,33 @@ export const CreateTestAccountSchema = z.object({
|
|
|
78
115
|
accountId: z.number().optional(),
|
|
79
116
|
personalAccessKey: z.string().optional(),
|
|
80
117
|
});
|
|
118
|
+
export function mapBuildToJsonOutput(build, deployedBuildId) {
|
|
119
|
+
const { buildId, status, isAutoDeployEnabled, deployableState, platformVersion, uploadMessage, enqueuedAt, startedAt, finishedAt, createdAt, subbuildStatuses, } = build;
|
|
120
|
+
return {
|
|
121
|
+
buildId,
|
|
122
|
+
status,
|
|
123
|
+
isDeployed: buildId === deployedBuildId,
|
|
124
|
+
isAutoDeployEnabled,
|
|
125
|
+
deployableState,
|
|
126
|
+
platformVersion,
|
|
127
|
+
uploadMessage,
|
|
128
|
+
enqueuedAt,
|
|
129
|
+
startedAt,
|
|
130
|
+
finishedAt,
|
|
131
|
+
createdAt,
|
|
132
|
+
subbuildStatuses: subbuildStatuses.map(subbuild => ({
|
|
133
|
+
buildName: subbuild.buildName,
|
|
134
|
+
buildType: subbuild.buildType,
|
|
135
|
+
status: subbuild.status,
|
|
136
|
+
errorMessage: subbuild.errorMessage,
|
|
137
|
+
startedAt: subbuild.startedAt,
|
|
138
|
+
finishedAt: subbuild.finishedAt,
|
|
139
|
+
rootPath: subbuild.rootPath,
|
|
140
|
+
id: subbuild.id,
|
|
141
|
+
visible: subbuild.visible,
|
|
142
|
+
})),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
81
145
|
export function mapReleaseToJsonOutput(release) {
|
|
82
146
|
const { releaseTag, buildId, createdAt, components } = release;
|
|
83
147
|
return {
|
|
@@ -48,6 +48,7 @@ export async function createV2App(providedAuth, providedDistribution) {
|
|
|
48
48
|
const componentTypeToGateMap = {
|
|
49
49
|
[AppEventsKey]: FEATURES.APP_EVENTS,
|
|
50
50
|
'workflow-action-tool': FEATURES.AGENT_TOOLS,
|
|
51
|
+
'crm-bulk-action': FEATURES.APP_ACTIONS,
|
|
51
52
|
};
|
|
52
53
|
export async function calculateComponentTemplateChoices(components, authType, distribution, accountId, projectMetadata) {
|
|
53
54
|
const enabledComponents = [];
|
|
@@ -22,6 +22,10 @@ declare class LocalDevLogger {
|
|
|
22
22
|
cleanupError(): void;
|
|
23
23
|
cleanupSuccess(): void;
|
|
24
24
|
uploadInitiated(): void;
|
|
25
|
+
autoUploadScheduled(filePath: string): void;
|
|
26
|
+
autoUploadTriggered(): void;
|
|
27
|
+
autoUploadInProgress(): void;
|
|
28
|
+
autoUploadToggled(enabled: boolean): void;
|
|
25
29
|
deployInitiated(): void;
|
|
26
30
|
projectConfigMismatch(): void;
|
|
27
31
|
uploadError(error: unknown): void;
|
|
@@ -99,6 +99,10 @@ class LocalDevLogger {
|
|
|
99
99
|
uiLogger.log('');
|
|
100
100
|
uiLogger.log(lib.LocalDevManager.localDevUIAutoMessage(this.state.targetTestingAccountId, showWelcomeScreen));
|
|
101
101
|
}
|
|
102
|
+
if (this.state.autoUploadEnabled) {
|
|
103
|
+
uiLogger.log('');
|
|
104
|
+
uiLogger.log(lib.LocalDevManager.autoUploadEnabled);
|
|
105
|
+
}
|
|
102
106
|
uiLogger.log('');
|
|
103
107
|
uiLogger.log(lib.LocalDevManager.quitHelper);
|
|
104
108
|
uiLine();
|
|
@@ -122,6 +126,20 @@ class LocalDevLogger {
|
|
|
122
126
|
uploadInitiated() {
|
|
123
127
|
uiLogger.log(lib.LocalDevProcess.uploadInitiated);
|
|
124
128
|
}
|
|
129
|
+
autoUploadScheduled(filePath) {
|
|
130
|
+
uiLogger.debug(lib.LocalDevProcess.autoUploadScheduled(filePath));
|
|
131
|
+
}
|
|
132
|
+
autoUploadTriggered() {
|
|
133
|
+
uiLogger.debug(lib.LocalDevProcess.autoUploadTriggered);
|
|
134
|
+
}
|
|
135
|
+
autoUploadInProgress() {
|
|
136
|
+
uiLogger.debug(lib.LocalDevProcess.autoUploadInProgress);
|
|
137
|
+
}
|
|
138
|
+
autoUploadToggled(enabled) {
|
|
139
|
+
uiLogger.log('');
|
|
140
|
+
uiLogger.log(lib.LocalDevProcess.autoUploadToggled(enabled));
|
|
141
|
+
uiLogger.log('');
|
|
142
|
+
}
|
|
125
143
|
deployInitiated() {
|
|
126
144
|
uiLogger.log(lib.LocalDevProcess.deployInitiated);
|
|
127
145
|
}
|
|
@@ -8,6 +8,9 @@ declare class LocalDevProcess {
|
|
|
8
8
|
private _logger;
|
|
9
9
|
private devServerManager;
|
|
10
10
|
private devSessionManager;
|
|
11
|
+
private autoUploadTimeout;
|
|
12
|
+
private pendingAutoUpload;
|
|
13
|
+
private autoUploadStopped;
|
|
11
14
|
constructor(options: LocalDevStateConstructorOptions);
|
|
12
15
|
get projectDir(): string;
|
|
13
16
|
get projectData(): Project;
|
|
@@ -17,6 +20,10 @@ declare class LocalDevProcess {
|
|
|
17
20
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
18
21
|
};
|
|
19
22
|
get logger(): LocalDevLogger;
|
|
23
|
+
get autoUploadEnabled(): boolean;
|
|
24
|
+
setAutoUploadEnabled(enabled: boolean): void;
|
|
25
|
+
get autoUploadAvailable(): boolean;
|
|
26
|
+
private isAutoDeployEnabled;
|
|
20
27
|
private setupDevServers;
|
|
21
28
|
private startDevServers;
|
|
22
29
|
private cleanupDevServers;
|
|
@@ -27,10 +34,13 @@ declare class LocalDevProcess {
|
|
|
27
34
|
private openLocalDevUi;
|
|
28
35
|
private updateProjectData;
|
|
29
36
|
handleFileChange(filePath: string, event: string): Promise<void>;
|
|
30
|
-
handleConfigFileChange(): Promise<void>;
|
|
37
|
+
handleConfigFileChange(configFilePath: string): Promise<void>;
|
|
38
|
+
private scheduleAutoUpload;
|
|
39
|
+
private runAutoUpload;
|
|
31
40
|
start(): Promise<void>;
|
|
32
41
|
stop(showProgress?: boolean): Promise<void>;
|
|
33
42
|
uploadProject(): Promise<LocalDevProjectUploadResult>;
|
|
43
|
+
private performUpload;
|
|
34
44
|
deployLatestBuild(force?: boolean): Promise<LocalDevProjectDeployResult>;
|
|
35
45
|
addStateListener<K extends keyof LocalDevState>(key: K, listener: LocalDevStateListener<K>): void;
|
|
36
46
|
sendDevServerMessage(message: LocalDevServerMessage): void;
|
|
@@ -17,11 +17,15 @@ import { getLocalDevUiUrl } from '../urls.js';
|
|
|
17
17
|
import { CONFIG_LOCAL_STATE_FLAGS, PROJECT_DEPLOY_STATES, } from '../../constants.js';
|
|
18
18
|
import { lib } from '../../../lang/en.js';
|
|
19
19
|
import { debugError } from '../../errorHandlers/index.js';
|
|
20
|
+
const AUTO_UPLOAD_DEBOUNCE_MS = 2000;
|
|
20
21
|
class LocalDevProcess {
|
|
21
22
|
state;
|
|
22
23
|
_logger;
|
|
23
24
|
devServerManager;
|
|
24
25
|
devSessionManager;
|
|
26
|
+
autoUploadTimeout = null;
|
|
27
|
+
pendingAutoUpload = false;
|
|
28
|
+
autoUploadStopped = false;
|
|
25
29
|
constructor(options) {
|
|
26
30
|
this.state = new LocalDevState(options);
|
|
27
31
|
this._logger = new LocalDevLogger(this.state);
|
|
@@ -53,6 +57,27 @@ class LocalDevProcess {
|
|
|
53
57
|
get logger() {
|
|
54
58
|
return this._logger;
|
|
55
59
|
}
|
|
60
|
+
get autoUploadEnabled() {
|
|
61
|
+
return this.state.autoUploadEnabled;
|
|
62
|
+
}
|
|
63
|
+
setAutoUploadEnabled(enabled) {
|
|
64
|
+
this.state.autoUploadEnabled = enabled;
|
|
65
|
+
this.logger.autoUploadToggled(enabled);
|
|
66
|
+
if (!enabled) {
|
|
67
|
+
if (this.autoUploadTimeout) {
|
|
68
|
+
clearTimeout(this.autoUploadTimeout);
|
|
69
|
+
this.autoUploadTimeout = null;
|
|
70
|
+
}
|
|
71
|
+
this.pendingAutoUpload = false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
get autoUploadAvailable() {
|
|
75
|
+
return this.isAutoDeployEnabled();
|
|
76
|
+
}
|
|
77
|
+
isAutoDeployEnabled() {
|
|
78
|
+
const { deployedBuild, latestBuild } = this.state.projectData;
|
|
79
|
+
return (deployedBuild ?? latestBuild)?.isAutoDeployEnabled ?? true;
|
|
80
|
+
}
|
|
56
81
|
async setupDevServers() {
|
|
57
82
|
try {
|
|
58
83
|
await this.devServerManager.setup();
|
|
@@ -141,10 +166,52 @@ class LocalDevProcess {
|
|
|
141
166
|
catch (e) {
|
|
142
167
|
this.logger.fileChangeError(e);
|
|
143
168
|
}
|
|
169
|
+
this.scheduleAutoUpload(filePath);
|
|
144
170
|
}
|
|
145
|
-
async handleConfigFileChange() {
|
|
171
|
+
async handleConfigFileChange(configFilePath) {
|
|
146
172
|
await this.updateProjectNodes();
|
|
147
|
-
this.
|
|
173
|
+
if (this.state.autoUploadEnabled) {
|
|
174
|
+
this.scheduleAutoUpload(configFilePath);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
this.logger.uploadWarning();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
scheduleAutoUpload(changedPath) {
|
|
181
|
+
if (!this.state.autoUploadEnabled || this.autoUploadStopped) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
this.logger.autoUploadScheduled(changedPath ?? 'project files');
|
|
185
|
+
if (this.autoUploadTimeout) {
|
|
186
|
+
clearTimeout(this.autoUploadTimeout);
|
|
187
|
+
}
|
|
188
|
+
this.autoUploadTimeout = setTimeout(() => {
|
|
189
|
+
this.autoUploadTimeout = null;
|
|
190
|
+
void this.runAutoUpload();
|
|
191
|
+
}, AUTO_UPLOAD_DEBOUNCE_MS);
|
|
192
|
+
}
|
|
193
|
+
async runAutoUpload() {
|
|
194
|
+
if (this.autoUploadStopped) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (this.state.uploadInProgress) {
|
|
198
|
+
this.logger.autoUploadInProgress();
|
|
199
|
+
this.pendingAutoUpload = true;
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
this.logger.autoUploadTriggered();
|
|
203
|
+
try {
|
|
204
|
+
await this.uploadProject();
|
|
205
|
+
}
|
|
206
|
+
catch (e) {
|
|
207
|
+
this.logger.uploadError(e);
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
if (this.pendingAutoUpload) {
|
|
211
|
+
this.pendingAutoUpload = false;
|
|
212
|
+
this.scheduleAutoUpload();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
148
215
|
}
|
|
149
216
|
async start() {
|
|
150
217
|
this.logger.resetSpinnies();
|
|
@@ -153,18 +220,24 @@ class LocalDevProcess {
|
|
|
153
220
|
return this.state.actions.exit(EXIT_CODES.ERROR);
|
|
154
221
|
}
|
|
155
222
|
this.logger.startupMessage();
|
|
156
|
-
if (isConfigFlagEnabled(CONFIG_FLAGS.AUTO_OPEN_BROWSER, true)) {
|
|
157
|
-
this.openLocalDevUi();
|
|
158
|
-
}
|
|
159
223
|
await this.startDevServers();
|
|
160
224
|
const devSessionRegistered = await this.devSessionManager.registerSession();
|
|
161
225
|
if (!devSessionRegistered) {
|
|
162
226
|
return this.state.actions.exit(EXIT_CODES.ERROR);
|
|
163
227
|
}
|
|
228
|
+
if (isConfigFlagEnabled(CONFIG_FLAGS.AUTO_OPEN_BROWSER, true)) {
|
|
229
|
+
this.openLocalDevUi();
|
|
230
|
+
}
|
|
164
231
|
this.state.devServersStarted = true;
|
|
165
232
|
this.logger.monitorConsoleOutput();
|
|
166
233
|
}
|
|
167
234
|
async stop(showProgress = true) {
|
|
235
|
+
this.autoUploadStopped = true;
|
|
236
|
+
this.pendingAutoUpload = false;
|
|
237
|
+
if (this.autoUploadTimeout) {
|
|
238
|
+
clearTimeout(this.autoUploadTimeout);
|
|
239
|
+
this.autoUploadTimeout = null;
|
|
240
|
+
}
|
|
168
241
|
if (showProgress) {
|
|
169
242
|
this.logger.cleanupStart();
|
|
170
243
|
}
|
|
@@ -182,6 +255,15 @@ class LocalDevProcess {
|
|
|
182
255
|
return this.state.actions.exit(EXIT_CODES.SUCCESS);
|
|
183
256
|
}
|
|
184
257
|
async uploadProject() {
|
|
258
|
+
this.state.uploadInProgress = true;
|
|
259
|
+
try {
|
|
260
|
+
return await this.performUpload();
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
this.state.uploadInProgress = false;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async performUpload() {
|
|
185
267
|
this.logger.uploadInitiated();
|
|
186
268
|
const isUploadable = await this.projectConfigValidForUpload();
|
|
187
269
|
if (!isUploadable) {
|
|
@@ -21,8 +21,10 @@ declare class LocalDevState {
|
|
|
21
21
|
private _devServerMessage;
|
|
22
22
|
private _uploadWarnings;
|
|
23
23
|
private _devServersStarted;
|
|
24
|
+
private _autoUploadEnabled;
|
|
25
|
+
private _uploadInProgress;
|
|
24
26
|
actions: LocalDevActions;
|
|
25
|
-
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectData, debug, initialProjectNodes, initialProjectProfileData, profile, env, actions, }: LocalDevStateConstructorOptions);
|
|
27
|
+
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectData, debug, initialProjectNodes, initialProjectProfileData, profile, env, actions, autoUploadEnabled, }: LocalDevStateConstructorOptions);
|
|
26
28
|
private runListeners;
|
|
27
29
|
get targetProjectAccountId(): number;
|
|
28
30
|
get targetTestingAccountId(): number;
|
|
@@ -56,6 +58,10 @@ declare class LocalDevState {
|
|
|
56
58
|
get uploadWarnings(): Set<string>;
|
|
57
59
|
get devServersStarted(): boolean;
|
|
58
60
|
set devServersStarted(started: boolean);
|
|
61
|
+
get autoUploadEnabled(): boolean;
|
|
62
|
+
set autoUploadEnabled(autoUploadEnabled: boolean);
|
|
63
|
+
get uploadInProgress(): boolean;
|
|
64
|
+
set uploadInProgress(inProgress: boolean);
|
|
59
65
|
addUploadWarning(warning: string): void;
|
|
60
66
|
clearUploadWarnings(): void;
|
|
61
67
|
addListener<K extends keyof LocalDevState>(key: K, listener: LocalDevStateListener<K>): void;
|
|
@@ -16,8 +16,10 @@ class LocalDevState {
|
|
|
16
16
|
_devServerMessage;
|
|
17
17
|
_uploadWarnings;
|
|
18
18
|
_devServersStarted;
|
|
19
|
+
_autoUploadEnabled;
|
|
20
|
+
_uploadInProgress;
|
|
19
21
|
actions;
|
|
20
|
-
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectData, debug, initialProjectNodes, initialProjectProfileData, profile, env, actions, }) {
|
|
22
|
+
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectData, debug, initialProjectNodes, initialProjectProfileData, profile, env, actions, autoUploadEnabled, }) {
|
|
21
23
|
this._targetProjectAccountId = targetProjectAccountId;
|
|
22
24
|
this._targetTestingAccountId = targetTestingAccountId;
|
|
23
25
|
this._profile = profile;
|
|
@@ -33,6 +35,8 @@ class LocalDevState {
|
|
|
33
35
|
this._devServerMessage = LOCAL_DEV_SERVER_MESSAGE_TYPES.INITIAL;
|
|
34
36
|
this._uploadWarnings = new Set();
|
|
35
37
|
this._devServersStarted = false;
|
|
38
|
+
this._autoUploadEnabled = autoUploadEnabled || false;
|
|
39
|
+
this._uploadInProgress = false;
|
|
36
40
|
this.actions = actions;
|
|
37
41
|
this._listeners = {};
|
|
38
42
|
}
|
|
@@ -117,6 +121,20 @@ class LocalDevState {
|
|
|
117
121
|
this._devServersStarted = started;
|
|
118
122
|
this.runListeners('devServersStarted');
|
|
119
123
|
}
|
|
124
|
+
get autoUploadEnabled() {
|
|
125
|
+
return this._autoUploadEnabled;
|
|
126
|
+
}
|
|
127
|
+
set autoUploadEnabled(autoUploadEnabled) {
|
|
128
|
+
this._autoUploadEnabled = autoUploadEnabled;
|
|
129
|
+
this.runListeners('autoUploadEnabled');
|
|
130
|
+
}
|
|
131
|
+
get uploadInProgress() {
|
|
132
|
+
return this._uploadInProgress;
|
|
133
|
+
}
|
|
134
|
+
set uploadInProgress(inProgress) {
|
|
135
|
+
this._uploadInProgress = inProgress;
|
|
136
|
+
this.runListeners('uploadInProgress');
|
|
137
|
+
}
|
|
120
138
|
addUploadWarning(warning) {
|
|
121
139
|
this.uploadWarnings.add(warning);
|
|
122
140
|
this.runListeners('uploadWarnings');
|
|
@@ -16,7 +16,7 @@ class LocalDevWatcher {
|
|
|
16
16
|
}
|
|
17
17
|
handleWatchEvent(filePath, event, configPaths) {
|
|
18
18
|
if (configPaths.includes(filePath)) {
|
|
19
|
-
return this.localDevProcess.handleConfigFileChange();
|
|
19
|
+
return this.localDevProcess.handleConfigFileChange(filePath);
|
|
20
20
|
}
|
|
21
21
|
return this.localDevProcess.handleFileChange(filePath, event);
|
|
22
22
|
}
|
|
@@ -14,6 +14,7 @@ declare class LocalDevWebsocketServer {
|
|
|
14
14
|
private setupAppDataListener;
|
|
15
15
|
private setupUploadWarningsListener;
|
|
16
16
|
private setupDevServersStartedListener;
|
|
17
|
+
private setupUploadInProgressListener;
|
|
17
18
|
private setupStateListeners;
|
|
18
19
|
start(): Promise<void>;
|
|
19
20
|
shutdown(): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { addLocalStateFlag } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { LOCAL_DEV_UI_MESSAGE_SEND_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES, CONFIG_LOCAL_STATE_FLAGS, LOCAL_DEV_WEBSOCKET_SERVER_INSTANCE_ID, } from '../../constants.js';
|
|
3
3
|
import { removeAnsiCodes } from '../../ui/removeAnsiCodes.js';
|
|
4
|
-
import { isDeployWebsocketMessage, isViewedWelcomeScreenWebsocketMessage, isUploadWebsocketMessage, isAppInstallFailureWebsocketMessage, isAppInstallSuccessWebsocketMessage, isAppInstallInitiatedWebsocketMessage, } from './localDevWebsocketServerUtils.js';
|
|
4
|
+
import { isDeployWebsocketMessage, isViewedWelcomeScreenWebsocketMessage, isUploadWebsocketMessage, isAppInstallFailureWebsocketMessage, isAppInstallSuccessWebsocketMessage, isAppInstallInitiatedWebsocketMessage, isSetAutoUploadWebsocketMessage, } from './localDevWebsocketServerUtils.js';
|
|
5
5
|
import CLIWebSocketServer from '../../CLIWebSocketServer.js';
|
|
6
6
|
const LOCAL_DEV_WEBSOCKET_SERVER_VERSION = 2;
|
|
7
7
|
const LOG_PREFIX = '[LocalDevWebsocketServer]';
|
|
@@ -78,6 +78,12 @@ class LocalDevWebsocketServer {
|
|
|
78
78
|
this.handleAppInstallInitiated();
|
|
79
79
|
return true;
|
|
80
80
|
}
|
|
81
|
+
else if (isSetAutoUploadWebsocketMessage(message)) {
|
|
82
|
+
if (this.localDevProcess.autoUploadAvailable) {
|
|
83
|
+
this.localDevProcess.setAutoUploadEnabled(message.data.enabled);
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
81
87
|
return false;
|
|
82
88
|
}
|
|
83
89
|
sendProjectData(websocket) {
|
|
@@ -90,6 +96,9 @@ class LocalDevWebsocketServer {
|
|
|
90
96
|
deployedBuild: this.localDevProcess.projectData.deployedBuild,
|
|
91
97
|
targetProjectAccountId: this.localDevProcess.targetProjectAccountId,
|
|
92
98
|
targetTestingAccountId: this.localDevProcess.targetTestingAccountId,
|
|
99
|
+
autoUploadEnabled: this.localDevProcess.autoUploadAvailable
|
|
100
|
+
? this.localDevProcess.autoUploadEnabled
|
|
101
|
+
: undefined,
|
|
93
102
|
},
|
|
94
103
|
});
|
|
95
104
|
}
|
|
@@ -143,11 +152,24 @@ class LocalDevWebsocketServer {
|
|
|
143
152
|
this.localDevProcess.removeStateListener('devServersStarted', listener);
|
|
144
153
|
});
|
|
145
154
|
}
|
|
155
|
+
setupUploadInProgressListener(websocket) {
|
|
156
|
+
const listener = (uploadInProgress) => {
|
|
157
|
+
this.cliWebSocketServer.sendMessage(websocket, {
|
|
158
|
+
type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_IN_PROGRESS,
|
|
159
|
+
data: { uploadInProgress },
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
this.localDevProcess.addStateListener('uploadInProgress', listener);
|
|
163
|
+
websocket.on('close', () => {
|
|
164
|
+
this.localDevProcess.removeStateListener('uploadInProgress', listener);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
146
167
|
setupStateListeners(websocket) {
|
|
147
168
|
this.setupProjectNodesListener(websocket);
|
|
148
169
|
this.setupAppDataListener(websocket);
|
|
149
170
|
this.setupUploadWarningsListener(websocket);
|
|
150
171
|
this.setupDevServersStartedListener(websocket);
|
|
172
|
+
this.setupUploadInProgressListener(websocket);
|
|
151
173
|
}
|
|
152
174
|
async start() {
|
|
153
175
|
await this.cliWebSocketServer.start({
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { LocalDevDeployWebsocketMessage } from '../../../types/LocalDev.js';
|
|
1
|
+
import { LocalDevDeployWebsocketMessage, LocalDevSetAutoUploadWebsocketMessage } from '../../../types/LocalDev.js';
|
|
2
2
|
import { CLIWebSocketMessage } from '../../CLIWebSocketServer.js';
|
|
3
3
|
export declare function isUploadWebsocketMessage(message: CLIWebSocketMessage): boolean;
|
|
4
4
|
export declare function isDeployWebsocketMessage(message: CLIWebSocketMessage): message is LocalDevDeployWebsocketMessage;
|
|
5
|
+
export declare function isSetAutoUploadWebsocketMessage(message: CLIWebSocketMessage): message is LocalDevSetAutoUploadWebsocketMessage;
|
|
5
6
|
export declare function isViewedWelcomeScreenWebsocketMessage(message: CLIWebSocketMessage): boolean;
|
|
6
7
|
export declare function isAppInstallSuccessWebsocketMessage(message: CLIWebSocketMessage): boolean;
|
|
7
8
|
export declare function isAppInstallInitiatedWebsocketMessage(message: CLIWebSocketMessage): boolean;
|
|
@@ -5,6 +5,9 @@ export function isUploadWebsocketMessage(message) {
|
|
|
5
5
|
export function isDeployWebsocketMessage(message) {
|
|
6
6
|
return message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.DEPLOY;
|
|
7
7
|
}
|
|
8
|
+
export function isSetAutoUploadWebsocketMessage(message) {
|
|
9
|
+
return message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.SET_AUTO_UPLOAD;
|
|
10
|
+
}
|
|
8
11
|
export function isViewedWelcomeScreenWebsocketMessage(message) {
|
|
9
12
|
return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.VIEWED_WELCOME_SCREEN);
|
|
10
13
|
}
|
package/lib/projects/release.js
CHANGED
|
@@ -60,7 +60,7 @@ export async function resolveBuildId(accountId, projectName, buildOption, force)
|
|
|
60
60
|
export async function validateBuildForRelease(accountId, projectName, buildId) {
|
|
61
61
|
try {
|
|
62
62
|
const { data: build } = await getBuildStatus(accountId, projectName, buildId);
|
|
63
|
-
return meetsMinimumPlatformVersion(build.platformVersion, PLATFORM_VERSIONS.
|
|
63
|
+
return meetsMinimumPlatformVersion(build.platformVersion, PLATFORM_VERSIONS.v2027_03_BETA);
|
|
64
64
|
}
|
|
65
65
|
catch (e) {
|
|
66
66
|
if (isSpecifiedError(e, { statusCode: 404 })) {
|
|
@@ -20,6 +20,7 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
20
20
|
settings: "settings";
|
|
21
21
|
"app-event": "app-event";
|
|
22
22
|
"workflow-action-tool": "workflow-action-tool";
|
|
23
|
+
"crm-bulk-action": "crm-bulk-action";
|
|
23
24
|
page: "page";
|
|
24
25
|
webhooks: "webhooks";
|
|
25
26
|
"app-function": "app-function";
|
|
@@ -24,6 +24,7 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
24
24
|
settings: "settings";
|
|
25
25
|
"app-event": "app-event";
|
|
26
26
|
"workflow-action-tool": "workflow-action-tool";
|
|
27
|
+
"crm-bulk-action": "crm-bulk-action";
|
|
27
28
|
page: "page";
|
|
28
29
|
webhooks: "webhooks";
|
|
29
30
|
"app-function": "app-function";
|
|
@@ -6,6 +6,7 @@ export declare const features: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
|
6
6
|
settings: "settings";
|
|
7
7
|
"app-event": "app-event";
|
|
8
8
|
"workflow-action-tool": "workflow-action-tool";
|
|
9
|
+
"crm-bulk-action": "crm-bulk-action";
|
|
9
10
|
page: "page";
|
|
10
11
|
webhooks: "webhooks";
|
|
11
12
|
"app-function": "app-function";
|
|
@@ -18,8 +18,9 @@ export const features = z
|
|
|
18
18
|
'app-event',
|
|
19
19
|
'scim',
|
|
20
20
|
'page',
|
|
21
|
+
'crm-bulk-action',
|
|
21
22
|
]))
|
|
22
|
-
.describe('The features to include in the project, multiple options can be selected. "app-function" is also known as a private serverless function. "app-function-endpoint" is a serverless functions that is publicly accessible via endpoint. "workflow-action" is also known as a custom workflow action. "workflow-action-tool" is also known as agent tools.')
|
|
23
|
+
.describe('The features to include in the project, multiple options can be selected. "app-function" is also known as a private serverless function. "app-function-endpoint" is a serverless functions that is publicly accessible via endpoint. "workflow-action" is also known as a custom workflow action. "workflow-action-tool" is also known as agent tools. "crm-bulk-action" is an app actions extension that lets users act on multiple CRM records at once.')
|
|
23
24
|
.optional();
|
|
24
25
|
export const docsSearchQuery = z
|
|
25
26
|
.string()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.14.0-beta.1",
|
|
4
4
|
"description": "The official CLI for developing on HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": "https://github.com/HubSpot/hubspot-cli",
|
|
@@ -10,10 +10,9 @@
|
|
|
10
10
|
"!**/__tests__/**"
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@hubspot/local-dev-lib": "5.10.
|
|
14
|
-
"@hubspot/project-parsing-lib": "0.
|
|
15
|
-
"@hubspot/
|
|
16
|
-
"@hubspot/ui-extensions-dev-server": "2.1.0",
|
|
13
|
+
"@hubspot/local-dev-lib": "5.10.3",
|
|
14
|
+
"@hubspot/project-parsing-lib": "0.23.0",
|
|
15
|
+
"@hubspot/ui-extensions-dev-server": "2.1.2",
|
|
17
16
|
"@inquirer/prompts": "7.1.0",
|
|
18
17
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
19
18
|
"archiver": "7.0.1",
|
|
@@ -21,13 +20,13 @@
|
|
|
21
20
|
"chokidar": "3.6.0",
|
|
22
21
|
"cli-cursor": "3.1.0",
|
|
23
22
|
"cli-progress": "3.12.0",
|
|
24
|
-
"express": "4.22.
|
|
23
|
+
"express": "4.22.2",
|
|
25
24
|
"findup-sync": "4.0.0",
|
|
26
25
|
"fs-extra": "8.1.0",
|
|
27
26
|
"ink": "6.6.0",
|
|
28
27
|
"ink-spinner": "5.0.0",
|
|
29
28
|
"ink-text-input": "6.0.0",
|
|
30
|
-
"js-yaml": "4.
|
|
29
|
+
"js-yaml": "4.3.1",
|
|
31
30
|
"minimatch": "10.2.5",
|
|
32
31
|
"moment": "2.30.1",
|
|
33
32
|
"open": "7.4.2",
|
|
@@ -36,9 +35,9 @@
|
|
|
36
35
|
"semver": "7.6.3",
|
|
37
36
|
"strip-ansi": "7.1.0",
|
|
38
37
|
"table": "6.9.0",
|
|
39
|
-
"tmp": "0.2.
|
|
38
|
+
"tmp": "0.2.7",
|
|
40
39
|
"update-notifier": "7.3.1",
|
|
41
|
-
"ws": "8.
|
|
40
|
+
"ws": "8.21.0",
|
|
42
41
|
"yargs": "17.7.2",
|
|
43
42
|
"yargs-parser": "21.1.1",
|
|
44
43
|
"zod": "^4.4.3"
|
|
@@ -61,7 +60,7 @@
|
|
|
61
60
|
"@typescript-eslint/eslint-plugin": "^8.30.1",
|
|
62
61
|
"@typescript-eslint/parser": "^8.11.0",
|
|
63
62
|
"@vitest/coverage-v8": "^2.1.9",
|
|
64
|
-
"axios": "1.
|
|
63
|
+
"axios": "1.19.0",
|
|
65
64
|
"eslint": "^8.56.0",
|
|
66
65
|
"eslint-plugin-import": "^2.31.0",
|
|
67
66
|
"husky": "^4.3.8",
|
|
@@ -125,6 +124,8 @@
|
|
|
125
124
|
},
|
|
126
125
|
"resolutions": {
|
|
127
126
|
"eslint-visitor-keys": "4.2.0",
|
|
128
|
-
"@eslint-community/eslint-utils": "4.9.0"
|
|
127
|
+
"@eslint-community/eslint-utils": "4.9.0",
|
|
128
|
+
"@opentelemetry/core": "2.10.0",
|
|
129
|
+
"axios": "1.19.0"
|
|
129
130
|
}
|
|
130
131
|
}
|
package/types/LocalDev.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export type LocalDevStateConstructorOptions = {
|
|
|
25
25
|
initialProjectProfileData: HSProfileVariables;
|
|
26
26
|
env: Environment;
|
|
27
27
|
actions: LocalDevActions;
|
|
28
|
+
autoUploadEnabled?: boolean;
|
|
28
29
|
};
|
|
29
30
|
export type LocalDevDeployWebsocketMessage = {
|
|
30
31
|
type: typeof LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.DEPLOY;
|
|
@@ -32,6 +33,12 @@ export type LocalDevDeployWebsocketMessage = {
|
|
|
32
33
|
force: boolean;
|
|
33
34
|
};
|
|
34
35
|
};
|
|
36
|
+
export type LocalDevSetAutoUploadWebsocketMessage = {
|
|
37
|
+
type: typeof LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.SET_AUTO_UPLOAD;
|
|
38
|
+
data: {
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
35
42
|
export type LocalDevStateListener<K extends keyof LocalDevState> = (value: LocalDevState[K]) => void;
|
|
36
43
|
export type AppLocalDevData = {
|
|
37
44
|
id: number;
|
package/types/Yargs.d.ts
CHANGED