@hubspot/cli 7.6.0-beta.13 → 7.6.0-beta.14
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/__tests__/getStarted.test.js +2 -2
- package/commands/__tests__/mcp.test.js +1 -1
- package/commands/__tests__/project.test.js +0 -3
- package/commands/app/__tests__/migrate.test.js +0 -1
- package/commands/app/migrate.js +4 -5
- package/commands/app/secret/add.js +2 -1
- package/commands/app/secret/delete.js +2 -1
- package/commands/app/secret/list.js +2 -1
- package/commands/app/secret/update.js +2 -1
- package/commands/app/secret.js +2 -1
- package/commands/app.js +2 -2
- package/commands/config/set.js +0 -1
- package/commands/getStarted.d.ts +0 -2
- package/commands/getStarted.js +2 -2
- package/commands/mcp/__tests__/setup.test.js +2 -2
- package/commands/mcp/setup.js +2 -2
- package/commands/mcp.js +2 -2
- package/commands/project/__tests__/create.test.js +6 -6
- package/commands/project/__tests__/deploy.test.js +0 -3
- package/commands/project/__tests__/devUnifiedFlow.test.js +2 -4
- package/commands/project/__tests__/logs.test.js +0 -3
- package/commands/project/__tests__/migrate.test.js +1 -2
- package/commands/project/__tests__/migrateApp.test.js +1 -2
- package/commands/project/__tests__/profile.test.js +1 -1
- package/commands/project/add.js +1 -5
- package/commands/project/create.js +3 -9
- package/commands/project/deploy.js +2 -2
- package/commands/project/dev/index.js +4 -3
- package/commands/project/dev/unifiedFlow.js +1 -2
- package/commands/project/download.js +1 -2
- package/commands/project/installDeps.js +1 -2
- package/commands/project/listBuilds.js +2 -2
- package/commands/project/logs.js +2 -2
- package/commands/project/migrate.js +15 -6
- package/commands/project/migrateApp.js +1 -2
- package/commands/project/open.js +1 -2
- package/commands/project/profile/add.js +3 -3
- package/commands/project/profile/delete.js +1 -2
- package/commands/project/profile.js +2 -3
- package/commands/project/upload.js +2 -2
- package/commands/project/validate.js +1 -1
- package/commands/project/watch.js +2 -2
- package/commands/project.js +1 -2
- package/lang/en.d.ts +11 -3
- package/lang/en.js +12 -4
- package/lib/constants.d.ts +4 -0
- package/lib/constants.js +4 -0
- package/lib/mcp/setup.js +1 -1
- package/lib/middleware/fireAlarmMiddleware.js +15 -5
- package/lib/projects/__tests__/LocalDevProcess.test.js +227 -16
- package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +16 -21
- package/lib/projects/__tests__/deploy.test.js +71 -6
- package/lib/projects/create/__tests__/v3.test.js +4 -4
- package/lib/projects/create/v3.js +2 -2
- package/lib/projects/localDev/LocalDevLogger.d.ts +4 -0
- package/lib/projects/localDev/LocalDevLogger.js +22 -0
- package/lib/projects/localDev/LocalDevProcess.d.ts +7 -5
- package/lib/projects/localDev/LocalDevProcess.js +90 -19
- package/lib/projects/localDev/LocalDevState.d.ts +9 -8
- package/lib/projects/localDev/LocalDevState.js +18 -17
- package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +2 -0
- package/lib/projects/localDev/LocalDevWebsocketServer.js +55 -23
- package/lib/projects/localDev/localDevWebsocketServerUtils.d.ts +4 -0
- package/lib/projects/localDev/localDevWebsocketServerUtils.js +10 -0
- package/lib/projects/pollProjectBuildAndDeploy.js +4 -4
- package/lib/prompts/projectAddPrompt.js +3 -1
- package/lib/prompts/promptUtils.js +3 -0
- package/lib/prompts/selectProjectTemplatePrompt.js +2 -0
- package/package.json +4 -4
- package/types/LocalDev.d.ts +19 -3
- package/ui/index.js +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { translateForLocalDev } from '@hubspot/project-parsing-lib';
|
|
2
2
|
import { hasLocalStateFlag } from '@hubspot/local-dev-lib/config';
|
|
3
|
+
import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import open from 'open';
|
|
5
6
|
import LocalDevState from './LocalDevState.js';
|
|
@@ -8,10 +9,13 @@ import DevServerManagerV2 from './DevServerManagerV2.js';
|
|
|
8
9
|
import { EXIT_CODES } from '../../enums/exitCodes.js';
|
|
9
10
|
import { getProjectConfig } from '../config.js';
|
|
10
11
|
import { handleProjectUpload } from '../upload.js';
|
|
12
|
+
import { handleProjectDeploy } from '../deploy.js';
|
|
11
13
|
import { pollProjectBuildAndDeploy } from '../pollProjectBuildAndDeploy.js';
|
|
12
14
|
import { getLocalDevUiUrl } from '../urls.js';
|
|
13
|
-
import { CONFIG_LOCAL_STATE_FLAGS } from '../../constants.js';
|
|
15
|
+
import { CONFIG_LOCAL_STATE_FLAGS, PROJECT_DEPLOY_STATES, } from '../../constants.js';
|
|
14
16
|
import { isAutoOpenBrowserEnabled } from '../../configOptions.js';
|
|
17
|
+
import { lib } from '../../../lang/en.js';
|
|
18
|
+
import { debugError } from '../../errorHandlers/index.js';
|
|
15
19
|
class LocalDevProcess {
|
|
16
20
|
state;
|
|
17
21
|
_logger;
|
|
@@ -27,11 +31,8 @@ class LocalDevProcess {
|
|
|
27
31
|
get projectDir() {
|
|
28
32
|
return this.state.projectDir;
|
|
29
33
|
}
|
|
30
|
-
get
|
|
31
|
-
return this.state.
|
|
32
|
-
}
|
|
33
|
-
get projectName() {
|
|
34
|
-
return this.state.projectName;
|
|
34
|
+
get projectData() {
|
|
35
|
+
return this.state.projectData;
|
|
35
36
|
}
|
|
36
37
|
get targetProjectAccountId() {
|
|
37
38
|
return this.state.targetProjectAccountId;
|
|
@@ -87,34 +88,43 @@ class LocalDevProcess {
|
|
|
87
88
|
});
|
|
88
89
|
return true;
|
|
89
90
|
}
|
|
90
|
-
getIntermediateRepresentation(
|
|
91
|
+
getIntermediateRepresentation(projectNodesAtLastDeploy) {
|
|
91
92
|
return translateForLocalDev({
|
|
92
93
|
projectSourceDir: path.join(this.state.projectDir, this.state.projectConfig.srcDir),
|
|
93
94
|
platformVersion: this.state.projectConfig.platformVersion,
|
|
94
95
|
accountId: this.state.targetProjectAccountId,
|
|
95
96
|
}, {
|
|
96
|
-
projectNodesAtLastUpload,
|
|
97
|
+
projectNodesAtLastUpload: projectNodesAtLastDeploy,
|
|
97
98
|
profile: this.state.profile,
|
|
98
99
|
});
|
|
99
100
|
}
|
|
100
101
|
async updateProjectNodes() {
|
|
101
|
-
const intermediateRepresentation = await this.getIntermediateRepresentation(this.state.
|
|
102
|
+
const intermediateRepresentation = await this.getIntermediateRepresentation(this.state.projectNodesAtLastDeploy);
|
|
102
103
|
this.state.projectNodes =
|
|
103
104
|
intermediateRepresentation.intermediateNodesIndexedByUid;
|
|
104
105
|
this.state.projectProfileData = intermediateRepresentation.profileData;
|
|
105
106
|
}
|
|
106
|
-
async
|
|
107
|
+
async updateProjectNodesAfterDeploy() {
|
|
107
108
|
const intermediateRepresentation = await this.getIntermediateRepresentation();
|
|
108
109
|
this.state.projectNodes =
|
|
109
110
|
intermediateRepresentation.intermediateNodesIndexedByUid;
|
|
110
111
|
this.state.projectProfileData = intermediateRepresentation.profileData;
|
|
111
|
-
this.state.
|
|
112
|
+
this.state.projectNodesAtLastDeploy =
|
|
112
113
|
intermediateRepresentation.intermediateNodesIndexedByUid;
|
|
113
114
|
}
|
|
114
115
|
openLocalDevUi() {
|
|
115
116
|
const showWelcomeScreen = !hasLocalStateFlag(CONFIG_LOCAL_STATE_FLAGS.LOCAL_DEV_UI_WELCOME);
|
|
116
117
|
open(getLocalDevUiUrl(this.state.targetTestingAccountId, showWelcomeScreen));
|
|
117
118
|
}
|
|
119
|
+
async updateProjectData() {
|
|
120
|
+
try {
|
|
121
|
+
const { data: projectData } = await fetchProject(this.state.targetProjectAccountId, this.state.projectConfig.name);
|
|
122
|
+
this.state.projectData = projectData;
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
debugError(e);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
118
128
|
async handleFileChange(filePath, event) {
|
|
119
129
|
await this.updateProjectNodes();
|
|
120
130
|
try {
|
|
@@ -162,24 +172,85 @@ class LocalDevProcess {
|
|
|
162
172
|
const isUploadable = await this.projectConfigValidForUpload();
|
|
163
173
|
if (!isUploadable) {
|
|
164
174
|
this.logger.projectConfigMismatch();
|
|
165
|
-
return
|
|
175
|
+
return {
|
|
176
|
+
uploadSuccess: false,
|
|
177
|
+
buildSuccess: false,
|
|
178
|
+
deploySuccess: false,
|
|
179
|
+
};
|
|
166
180
|
}
|
|
167
|
-
const { uploadError } = await handleProjectUpload({
|
|
181
|
+
const { uploadError, result } = await handleProjectUpload({
|
|
168
182
|
accountId: this.state.targetProjectAccountId,
|
|
169
183
|
projectConfig: this.state.projectConfig,
|
|
170
184
|
projectDir: this.state.projectDir,
|
|
171
185
|
callbackFunc: pollProjectBuildAndDeploy,
|
|
172
186
|
sendIR: true,
|
|
173
|
-
skipValidation: true,
|
|
174
187
|
});
|
|
188
|
+
const deploy = result?.deployResult;
|
|
175
189
|
if (uploadError) {
|
|
176
190
|
this.logger.uploadError(uploadError);
|
|
177
|
-
return
|
|
191
|
+
return {
|
|
192
|
+
uploadSuccess: false,
|
|
193
|
+
buildSuccess: false,
|
|
194
|
+
deploySuccess: false,
|
|
195
|
+
deployId: deploy?.deployId,
|
|
196
|
+
};
|
|
178
197
|
}
|
|
179
|
-
await this.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
198
|
+
await this.updateProjectData();
|
|
199
|
+
if (deploy && deploy.status === PROJECT_DEPLOY_STATES.FAILURE) {
|
|
200
|
+
return {
|
|
201
|
+
uploadSuccess: false,
|
|
202
|
+
buildSuccess: true,
|
|
203
|
+
deploySuccess: false,
|
|
204
|
+
deployId: deploy.deployId,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
else if (!deploy) {
|
|
208
|
+
this.logger.uploadSuccessAutoDeployDisabled();
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
await this.updateProjectNodesAfterDeploy();
|
|
212
|
+
this.state.clearUploadWarnings();
|
|
213
|
+
this.logger.uploadSuccess();
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
uploadSuccess: true,
|
|
217
|
+
buildSuccess: true,
|
|
218
|
+
deploySuccess: Boolean(deploy),
|
|
219
|
+
deployId: deploy?.deployId,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
async deployLatestBuild(force = false) {
|
|
223
|
+
this.logger.deployInitiated();
|
|
224
|
+
if (!this.state.projectData.latestBuild) {
|
|
225
|
+
this.logger.deployError(lib.LocalDevProcess.noBuildToDeploy);
|
|
226
|
+
return {
|
|
227
|
+
success: false,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
let deploy;
|
|
231
|
+
try {
|
|
232
|
+
deploy = await handleProjectDeploy(this.state.targetProjectAccountId, this.state.projectConfig.name, this.state.projectData.latestBuild.buildId, true, force);
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
this.logger.deployError(error);
|
|
236
|
+
return {
|
|
237
|
+
success: false,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
const success = deploy?.status === PROJECT_DEPLOY_STATES.SUCCESS;
|
|
241
|
+
if (success) {
|
|
242
|
+
await this.updateProjectData();
|
|
243
|
+
this.logger.deploySuccess();
|
|
244
|
+
await this.updateProjectNodesAfterDeploy();
|
|
245
|
+
this.state.clearUploadWarnings();
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
this.logger.deployError();
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
success,
|
|
252
|
+
deployId: deploy?.deployId,
|
|
253
|
+
};
|
|
183
254
|
}
|
|
184
255
|
addStateListener(key, listener) {
|
|
185
256
|
this.state.addListener(key, listener);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IntermediateRepresentationNodeLocalDev, HSProfileVariables } from '@hubspot/project-parsing-lib/src/lib/types.js';
|
|
2
2
|
import { Environment } from '@hubspot/local-dev-lib/types/Config';
|
|
3
|
+
import { Project } from '@hubspot/local-dev-lib/types/Project';
|
|
3
4
|
import { ProjectConfig } from '../../../types/Projects.js';
|
|
4
5
|
import { LocalDevStateConstructorOptions, LocalDevStateListener, AppLocalDevData, LocalDevServerMessage } from '../../../types/LocalDev.js';
|
|
5
6
|
declare class LocalDevState {
|
|
@@ -8,26 +9,23 @@ declare class LocalDevState {
|
|
|
8
9
|
private _profile?;
|
|
9
10
|
private _projectConfig;
|
|
10
11
|
private _projectDir;
|
|
11
|
-
private
|
|
12
|
-
private _projectName;
|
|
12
|
+
private _projectData;
|
|
13
13
|
private _debug;
|
|
14
14
|
private _projectNodes;
|
|
15
15
|
private _projectProfileData;
|
|
16
|
-
private
|
|
16
|
+
private _projectNodesAtLastDeploy;
|
|
17
17
|
private _env;
|
|
18
18
|
private _listeners;
|
|
19
19
|
private _appData;
|
|
20
20
|
private _devServerMessage;
|
|
21
21
|
private _uploadWarnings;
|
|
22
|
-
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir,
|
|
22
|
+
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectData, debug, initialProjectNodes, initialProjectProfileData, profile, env, }: LocalDevStateConstructorOptions);
|
|
23
23
|
private runListeners;
|
|
24
24
|
get targetProjectAccountId(): number;
|
|
25
25
|
get targetTestingAccountId(): number;
|
|
26
26
|
get profile(): string | undefined;
|
|
27
27
|
get projectConfig(): ProjectConfig;
|
|
28
28
|
get projectDir(): string;
|
|
29
|
-
get projectId(): number;
|
|
30
|
-
get projectName(): string;
|
|
31
29
|
get debug(): boolean;
|
|
32
30
|
get projectNodes(): {
|
|
33
31
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
@@ -37,12 +35,15 @@ declare class LocalDevState {
|
|
|
37
35
|
});
|
|
38
36
|
get projectProfileData(): HSProfileVariables;
|
|
39
37
|
set projectProfileData(profileData: HSProfileVariables);
|
|
40
|
-
get
|
|
38
|
+
get projectNodesAtLastDeploy(): {
|
|
41
39
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
42
40
|
};
|
|
43
|
-
set
|
|
41
|
+
set projectNodesAtLastDeploy(nodes: {
|
|
44
42
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
45
43
|
});
|
|
44
|
+
get projectData(): Project;
|
|
45
|
+
get projectId(): number;
|
|
46
|
+
set projectData(projectData: Project);
|
|
46
47
|
get env(): Environment;
|
|
47
48
|
get appData(): Record<string, AppLocalDevData>;
|
|
48
49
|
getAppDataByUid(uid: string): AppLocalDevData | undefined;
|
|
@@ -5,28 +5,26 @@ class LocalDevState {
|
|
|
5
5
|
_profile;
|
|
6
6
|
_projectConfig;
|
|
7
7
|
_projectDir;
|
|
8
|
-
|
|
9
|
-
_projectName;
|
|
8
|
+
_projectData;
|
|
10
9
|
_debug;
|
|
11
10
|
_projectNodes;
|
|
12
11
|
_projectProfileData;
|
|
13
|
-
|
|
12
|
+
_projectNodesAtLastDeploy;
|
|
14
13
|
_env;
|
|
15
14
|
_listeners;
|
|
16
15
|
_appData;
|
|
17
16
|
_devServerMessage;
|
|
18
17
|
_uploadWarnings;
|
|
19
|
-
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir,
|
|
18
|
+
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectData, debug, initialProjectNodes, initialProjectProfileData, profile, env, }) {
|
|
20
19
|
this._targetProjectAccountId = targetProjectAccountId;
|
|
21
20
|
this._targetTestingAccountId = targetTestingAccountId;
|
|
22
21
|
this._profile = profile;
|
|
23
22
|
this._projectConfig = projectConfig;
|
|
24
23
|
this._projectDir = projectDir;
|
|
25
|
-
this.
|
|
26
|
-
this._projectName = projectName;
|
|
24
|
+
this._projectData = projectData;
|
|
27
25
|
this._debug = debug || false;
|
|
28
26
|
this._projectNodes = initialProjectNodes;
|
|
29
|
-
this.
|
|
27
|
+
this._projectNodesAtLastDeploy = initialProjectNodes;
|
|
30
28
|
this._projectProfileData = initialProjectProfileData;
|
|
31
29
|
this._env = env;
|
|
32
30
|
this._appData = {};
|
|
@@ -54,12 +52,6 @@ class LocalDevState {
|
|
|
54
52
|
get projectDir() {
|
|
55
53
|
return this._projectDir;
|
|
56
54
|
}
|
|
57
|
-
get projectId() {
|
|
58
|
-
return this._projectId;
|
|
59
|
-
}
|
|
60
|
-
get projectName() {
|
|
61
|
-
return this._projectName;
|
|
62
|
-
}
|
|
63
55
|
get debug() {
|
|
64
56
|
return this._debug;
|
|
65
57
|
}
|
|
@@ -76,11 +68,20 @@ class LocalDevState {
|
|
|
76
68
|
set projectProfileData(profileData) {
|
|
77
69
|
this._projectProfileData = profileData;
|
|
78
70
|
}
|
|
79
|
-
get
|
|
80
|
-
return structuredClone(this.
|
|
71
|
+
get projectNodesAtLastDeploy() {
|
|
72
|
+
return structuredClone(this._projectNodesAtLastDeploy);
|
|
73
|
+
}
|
|
74
|
+
set projectNodesAtLastDeploy(nodes) {
|
|
75
|
+
this._projectNodesAtLastDeploy = nodes;
|
|
76
|
+
}
|
|
77
|
+
get projectData() {
|
|
78
|
+
return structuredClone(this._projectData);
|
|
79
|
+
}
|
|
80
|
+
get projectId() {
|
|
81
|
+
return this.projectData.id;
|
|
81
82
|
}
|
|
82
|
-
set
|
|
83
|
-
this.
|
|
83
|
+
set projectData(projectData) {
|
|
84
|
+
this._projectData = projectData;
|
|
84
85
|
}
|
|
85
86
|
get env() {
|
|
86
87
|
return this._env;
|
|
@@ -9,7 +9,9 @@ declare class LocalDevWebsocketServer {
|
|
|
9
9
|
private logError;
|
|
10
10
|
private sendMessage;
|
|
11
11
|
private handleUpload;
|
|
12
|
+
private handleDeploy;
|
|
12
13
|
private setupMessageHandlers;
|
|
14
|
+
private sendCliMetadata;
|
|
13
15
|
private sendProjectData;
|
|
14
16
|
private setupProjectNodesListener;
|
|
15
17
|
private setupAppDataListener;
|
|
@@ -2,10 +2,13 @@ import { WebSocketServer } from 'ws';
|
|
|
2
2
|
import { isPortManagerServerRunning, requestPorts, } from '@hubspot/local-dev-lib/portManager';
|
|
3
3
|
import { logger } from '@hubspot/local-dev-lib/logger';
|
|
4
4
|
import { addLocalStateFlag } from '@hubspot/local-dev-lib/config';
|
|
5
|
-
import { LOCAL_DEV_UI_MESSAGE_SEND_TYPES,
|
|
5
|
+
import { LOCAL_DEV_UI_MESSAGE_SEND_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES, CONFIG_LOCAL_STATE_FLAGS, } from '../../constants.js';
|
|
6
6
|
import { lib } from '../../../lang/en.js';
|
|
7
7
|
import { removeAnsiCodes } from '../../ui/removeAnsiCodes.js';
|
|
8
|
+
import { isDeployWebsocketMessage, isViewedWelcomeScreenWebsocketMessage, isUploadWebsocketMessage, } from './localDevWebsocketServerUtils.js';
|
|
9
|
+
import pkg from '../../../package.json' with { type: 'json' };
|
|
8
10
|
const SERVER_INSTANCE_ID = 'local-dev-ui-websocket-server';
|
|
11
|
+
const LOCAL_DEV_WEBSOCKET_SERVER_VERSION = 1;
|
|
9
12
|
const LOG_PREFIX = '[LocalDevWebsocketServer]';
|
|
10
13
|
class LocalDevWebsocketServer {
|
|
11
14
|
server;
|
|
@@ -35,17 +38,32 @@ class LocalDevWebsocketServer {
|
|
|
35
38
|
websocket.send(JSON.stringify(message));
|
|
36
39
|
}
|
|
37
40
|
async handleUpload(websocket) {
|
|
38
|
-
const uploadSuccess = await this.localDevProcess.uploadProject();
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
const { uploadSuccess, buildSuccess, deploySuccess, deployId } = await this.localDevProcess.uploadProject();
|
|
42
|
+
this.sendMessage(websocket, {
|
|
43
|
+
type: uploadSuccess
|
|
44
|
+
? LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_SUCCESS
|
|
45
|
+
: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_FAILURE,
|
|
46
|
+
data: {
|
|
47
|
+
latestBuild: this.localDevProcess.projectData.latestBuild,
|
|
48
|
+
deployedBuild: this.localDevProcess.projectData.deployedBuild,
|
|
49
|
+
buildSuccess,
|
|
50
|
+
deploySuccess,
|
|
51
|
+
deployId,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async handleDeploy(websocket, force) {
|
|
56
|
+
const { success, deployId } = await this.localDevProcess.deployLatestBuild(force);
|
|
57
|
+
this.sendMessage(websocket, {
|
|
58
|
+
type: success
|
|
59
|
+
? LOCAL_DEV_UI_MESSAGE_SEND_TYPES.DEPLOY_SUCCESS
|
|
60
|
+
: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.DEPLOY_FAILURE,
|
|
61
|
+
data: {
|
|
62
|
+
latestBuild: this.localDevProcess.projectData.latestBuild,
|
|
63
|
+
deployedBuild: this.localDevProcess.projectData.deployedBuild,
|
|
64
|
+
latestDeployId: deployId,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
49
67
|
}
|
|
50
68
|
setupMessageHandlers(websocket) {
|
|
51
69
|
websocket.on('message', data => {
|
|
@@ -55,15 +73,17 @@ class LocalDevWebsocketServer {
|
|
|
55
73
|
this.logError(lib.LocalDevWebsocketServer.errors.missingTypeField(data.toString()));
|
|
56
74
|
return;
|
|
57
75
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
76
|
+
if (isUploadWebsocketMessage(message)) {
|
|
77
|
+
this.handleUpload(websocket);
|
|
78
|
+
}
|
|
79
|
+
else if (isDeployWebsocketMessage(message)) {
|
|
80
|
+
this.handleDeploy(websocket, message.data.force);
|
|
81
|
+
}
|
|
82
|
+
else if (isViewedWelcomeScreenWebsocketMessage(message)) {
|
|
83
|
+
addLocalStateFlag(CONFIG_LOCAL_STATE_FLAGS.LOCAL_DEV_UI_WELCOME);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.logError(lib.LocalDevWebsocketServer.errors.unknownMessageType(message.type));
|
|
67
87
|
}
|
|
68
88
|
}
|
|
69
89
|
catch (e) {
|
|
@@ -71,12 +91,23 @@ class LocalDevWebsocketServer {
|
|
|
71
91
|
}
|
|
72
92
|
});
|
|
73
93
|
}
|
|
94
|
+
sendCliMetadata(websocket) {
|
|
95
|
+
this.sendMessage(websocket, {
|
|
96
|
+
type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.CLI_METADATA,
|
|
97
|
+
data: {
|
|
98
|
+
cliVersion: pkg.version,
|
|
99
|
+
localDevWebsocketServerVersion: LOCAL_DEV_WEBSOCKET_SERVER_VERSION,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
74
103
|
sendProjectData(websocket) {
|
|
75
104
|
this.sendMessage(websocket, {
|
|
76
105
|
type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPDATE_PROJECT_DATA,
|
|
77
106
|
data: {
|
|
78
|
-
projectName: this.localDevProcess.
|
|
79
|
-
projectId: this.localDevProcess.
|
|
107
|
+
projectName: this.localDevProcess.projectData.name,
|
|
108
|
+
projectId: this.localDevProcess.projectData.id,
|
|
109
|
+
latestBuild: this.localDevProcess.projectData.latestBuild,
|
|
110
|
+
deployedBuild: this.localDevProcess.projectData.deployedBuild,
|
|
80
111
|
targetProjectAccountId: this.localDevProcess.targetProjectAccountId,
|
|
81
112
|
targetTestingAccountId: this.localDevProcess.targetTestingAccountId,
|
|
82
113
|
},
|
|
@@ -139,6 +170,7 @@ class LocalDevWebsocketServer {
|
|
|
139
170
|
ws.close(1008, lib.LocalDevWebsocketServer.errors.originNotAllowed(origin));
|
|
140
171
|
return;
|
|
141
172
|
}
|
|
173
|
+
this.sendCliMetadata(ws);
|
|
142
174
|
this.sendProjectData(ws);
|
|
143
175
|
this.setupMessageHandlers(ws);
|
|
144
176
|
this.setupStateListeners(ws);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { LocalDevDeployWebsocketMessage, LocalDevWebsocketMessage } from '../../../types/LocalDev.js';
|
|
2
|
+
export declare function isUploadWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
|
|
3
|
+
export declare function isDeployWebsocketMessage(message: LocalDevWebsocketMessage): message is LocalDevDeployWebsocketMessage;
|
|
4
|
+
export declare function isViewedWelcomeScreenWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES } from '../../constants.js';
|
|
2
|
+
export function isUploadWebsocketMessage(message) {
|
|
3
|
+
return message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.UPLOAD;
|
|
4
|
+
}
|
|
5
|
+
export function isDeployWebsocketMessage(message) {
|
|
6
|
+
return message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.DEPLOY;
|
|
7
|
+
}
|
|
8
|
+
export function isViewedWelcomeScreenWebsocketMessage(message) {
|
|
9
|
+
return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.VIEWED_WELCOME_SCREEN);
|
|
10
|
+
}
|
|
@@ -278,10 +278,10 @@ export async function displayWarnLogs(accountId, projectName, taskId, isDeploy =
|
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
280
|
if (result && result.logs) {
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
uiLogger.warn(log
|
|
284
|
-
if (i <
|
|
281
|
+
const dedupedLogs = result.logs.reduce((acc, log) => acc.add(log.message), new Set());
|
|
282
|
+
Array.from(dedupedLogs).forEach((log, i) => {
|
|
283
|
+
uiLogger.warn(log);
|
|
284
|
+
if (i < dedupedLogs.size - 1) {
|
|
285
285
|
uiLogger.log('');
|
|
286
286
|
}
|
|
287
287
|
});
|
|
@@ -62,10 +62,12 @@ export async function projectAddPromptV3(components, selectedFeatures) {
|
|
|
62
62
|
const result = await promptUser([
|
|
63
63
|
{
|
|
64
64
|
name: 'componentTemplate',
|
|
65
|
-
message: lib.prompts.projectAddPrompt.
|
|
65
|
+
message: lib.prompts.projectAddPrompt.selectFeatures,
|
|
66
66
|
when: !selectedFeatures && selectedComponents.length === 0,
|
|
67
67
|
type: 'checkbox',
|
|
68
68
|
choices: components,
|
|
69
|
+
loop: false,
|
|
70
|
+
pageSize: components.length,
|
|
69
71
|
},
|
|
70
72
|
]);
|
|
71
73
|
if (!result.componentTemplate) {
|
|
@@ -133,6 +133,9 @@ function handleCheckboxPrompt(config) {
|
|
|
133
133
|
validate: config.validate,
|
|
134
134
|
loop: config.loop,
|
|
135
135
|
theme: PROMPT_THEME,
|
|
136
|
+
shortcuts: {
|
|
137
|
+
invert: null,
|
|
138
|
+
},
|
|
136
139
|
}).then(resp => ({ [config.name]: resp }));
|
|
137
140
|
}
|
|
138
141
|
function handleConfirmPrompt(config) {
|
|
@@ -51,6 +51,8 @@ export async function selectProjectTemplatePrompt(promptOptions, projectTemplate
|
|
|
51
51
|
selectedComponents.length === 0,
|
|
52
52
|
type: 'checkbox',
|
|
53
53
|
choices: componentTemplates,
|
|
54
|
+
loop: false,
|
|
55
|
+
pageSize: componentTemplates?.length,
|
|
54
56
|
},
|
|
55
57
|
]);
|
|
56
58
|
if (!result.componentTemplates) {
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "7.6.0-beta.
|
|
3
|
+
"version": "7.6.0-beta.14",
|
|
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",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@hubspot/local-dev-lib": "3.
|
|
10
|
-
"@hubspot/project-parsing-lib": "0.8.
|
|
9
|
+
"@hubspot/local-dev-lib": "3.19.0",
|
|
10
|
+
"@hubspot/project-parsing-lib": "0.8.5",
|
|
11
11
|
"@hubspot/serverless-dev-runtime": "7.0.6",
|
|
12
12
|
"@hubspot/theme-preview-dev-server": "0.0.10",
|
|
13
|
-
"@hubspot/ui-extensions-dev-server": "0.
|
|
13
|
+
"@hubspot/ui-extensions-dev-server": "0.10.0",
|
|
14
14
|
"archiver": "7.0.1",
|
|
15
15
|
"boxen": "8.0.1",
|
|
16
16
|
"chalk": "5.4.1",
|
package/types/LocalDev.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { HSProfileVariables, IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types.js';
|
|
2
2
|
import { Environment } from '@hubspot/local-dev-lib/types/Config';
|
|
3
3
|
import { ValueOf } from '@hubspot/local-dev-lib/types/Utils';
|
|
4
|
+
import { Project } from '@hubspot/local-dev-lib/types/Project';
|
|
4
5
|
import { ProjectConfig } from './Projects.js';
|
|
5
6
|
import LocalDevState from '../lib/projects/localDev/LocalDevState.js';
|
|
6
|
-
import { APP_INSTALLATION_STATES, LOCAL_DEV_SERVER_MESSAGE_TYPES } from '../lib/constants.js';
|
|
7
|
+
import { APP_INSTALLATION_STATES, LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES } from '../lib/constants.js';
|
|
7
8
|
export type LocalDevStateConstructorOptions = {
|
|
8
9
|
targetProjectAccountId: number;
|
|
9
10
|
targetTestingAccountId: number;
|
|
10
11
|
profile?: string;
|
|
11
12
|
projectConfig: ProjectConfig;
|
|
12
13
|
projectDir: string;
|
|
13
|
-
|
|
14
|
-
projectName: string;
|
|
14
|
+
projectData: Project;
|
|
15
15
|
debug?: boolean;
|
|
16
16
|
initialProjectNodes: {
|
|
17
17
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
@@ -23,6 +23,12 @@ export type LocalDevWebsocketMessage = {
|
|
|
23
23
|
type: string;
|
|
24
24
|
data?: unknown;
|
|
25
25
|
};
|
|
26
|
+
export type LocalDevDeployWebsocketMessage = {
|
|
27
|
+
type: typeof LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.DEPLOY;
|
|
28
|
+
data: {
|
|
29
|
+
force: boolean;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
26
32
|
export type LocalDevStateListener<K extends keyof LocalDevState> = (value: LocalDevState[K]) => void;
|
|
27
33
|
export type AppLocalDevData = {
|
|
28
34
|
id: number;
|
|
@@ -32,3 +38,13 @@ export type AppLocalDevData = {
|
|
|
32
38
|
scopeGroupIds: number[];
|
|
33
39
|
};
|
|
34
40
|
export type LocalDevServerMessage = ValueOf<typeof LOCAL_DEV_SERVER_MESSAGE_TYPES>;
|
|
41
|
+
export type LocalDevProjectUploadResult = {
|
|
42
|
+
uploadSuccess: boolean;
|
|
43
|
+
buildSuccess: boolean;
|
|
44
|
+
deploySuccess?: boolean;
|
|
45
|
+
deployId?: number;
|
|
46
|
+
};
|
|
47
|
+
export type LocalDevProjectDeployResult = {
|
|
48
|
+
success: boolean;
|
|
49
|
+
deployId?: number;
|
|
50
|
+
};
|
package/ui/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { render } from 'ink';
|
|
2
|
-
// Ink components will be enabled by setting the
|
|
2
|
+
// Ink components will be enabled by setting the HUBSPOT_ENABLE_INK environment variable
|
|
3
3
|
export async function renderInline(component) {
|
|
4
4
|
const { unmount } = render(component, { patchConsole: false });
|
|
5
5
|
unmount();
|