@hubspot/cli 7.7.0-experimental.3 → 7.7.2-experimental.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/bin/cli.js +96 -94
- package/commands/account/auth.js +51 -82
- package/commands/account.js +0 -2
- package/commands/app.js +0 -2
- package/commands/auth.js +2 -17
- package/commands/cms.js +0 -2
- package/commands/completion.js +0 -2
- package/commands/config/migrate.js +17 -36
- package/commands/config.js +0 -2
- package/commands/create.js +0 -2
- package/commands/customObject.js +0 -2
- package/commands/doctor.js +0 -2
- package/commands/feedback.js +0 -2
- package/commands/filemanager.js +0 -2
- package/commands/function.js +0 -2
- package/commands/hubdb.js +0 -2
- package/commands/init.js +1 -4
- package/commands/lint.js +0 -2
- package/commands/list.js +0 -2
- package/commands/module/marketplace-validate.js +6 -8
- package/commands/module.js +2 -1
- package/commands/mv.js +0 -2
- package/commands/open.js +0 -2
- package/commands/project/add.d.ts +5 -2
- package/commands/project/add.js +43 -80
- package/commands/project/create.d.ts +2 -8
- package/commands/project/create.js +84 -55
- package/commands/project/dev/deprecatedFlow.d.ts +8 -2
- package/commands/project/dev/deprecatedFlow.js +9 -1
- package/commands/project/dev/index.js +59 -34
- package/commands/project/dev/unifiedFlow.d.ts +10 -2
- package/commands/project/dev/unifiedFlow.js +28 -41
- package/commands/project.js +0 -2
- package/commands/remove.js +6 -14
- package/commands/sandbox.js +0 -2
- package/commands/secret.js +0 -2
- package/commands/theme/generate-selectors.js +7 -10
- package/commands/theme/marketplace-validate.js +6 -8
- package/commands/theme/preview.js +17 -18
- package/commands/theme.js +2 -4
- package/commands/upload.js +26 -65
- package/commands/watch.js +20 -32
- package/lang/en.d.ts +154 -95
- package/lang/en.js +156 -100
- package/lang/en.lyaml +3 -186
- package/lib/accountTypes.js +1 -3
- package/lib/commonOpts.d.ts +1 -3
- package/lib/commonOpts.js +1 -1
- package/lib/configMigrate.d.ts +2 -2
- package/lib/configMigrate.js +34 -69
- package/lib/constants.d.ts +23 -5
- package/lib/constants.js +24 -6
- package/lib/generateSelectors.js +3 -5
- package/lib/marketplaceValidate.d.ts +12 -2
- package/lib/marketplaceValidate.js +22 -29
- package/lib/middleware/configMiddleware.js +1 -0
- package/lib/middleware/fireAlarmMiddleware.d.ts +2 -2
- package/lib/middleware/fireAlarmMiddleware.js +5 -3
- package/lib/projects/add/legacyAddComponent.d.ts +5 -0
- package/lib/projects/add/legacyAddComponent.js +48 -0
- package/lib/projects/add/v3AddComponent.d.ts +8 -0
- package/lib/projects/add/v3AddComponent.js +85 -0
- package/lib/projects/components.d.ts +2 -0
- package/lib/projects/components.js +82 -0
- package/lib/projects/create/index.d.ts +23 -0
- package/lib/projects/create/index.js +33 -0
- package/lib/projects/create/legacy.d.ts +6 -0
- package/lib/projects/{create.js → create/legacy.js} +20 -11
- package/lib/projects/create/v3.d.ts +27 -0
- package/lib/projects/create/v3.js +158 -0
- package/lib/projects/localDev/AppDevModeInterface.d.ts +3 -2
- package/lib/projects/localDev/AppDevModeInterface.js +38 -8
- package/lib/projects/localDev/LocalDevProcess.d.ts +12 -5
- package/lib/projects/localDev/LocalDevProcess.js +47 -17
- package/lib/projects/localDev/LocalDevState.d.ts +16 -3
- package/lib/projects/localDev/LocalDevState.js +43 -2
- package/lib/projects/localDev/LocalDevWatcher.js +3 -6
- package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +3 -0
- package/lib/projects/localDev/LocalDevWebsocketServer.js +48 -9
- package/lib/projects/upload.js +6 -0
- package/lib/prompts/createProjectPrompt.d.ts +14 -5
- package/lib/prompts/createProjectPrompt.js +36 -13
- package/lib/prompts/projectAddPrompt.d.ts +5 -1
- package/lib/prompts/projectAddPrompt.js +35 -7
- package/lib/prompts/promptUtils.d.ts +0 -1
- package/lib/prompts/promptUtils.js +0 -2
- package/lib/prompts/setAsDefaultAccountPrompt.js +10 -0
- package/package.json +7 -6
- package/types/LocalDev.d.ts +11 -1
- package/types/Projects.d.ts +19 -2
- package/types/Yargs.d.ts +2 -0
- package/commands/testAccount/create.d.ts +0 -7
- package/commands/testAccount/create.js +0 -118
- package/commands/testAccount/delete.d.ts +0 -6
- package/commands/testAccount/delete.js +0 -42
- package/commands/testAccount.d.ts +0 -3
- package/commands/testAccount.js +0 -27
- package/lib/projects/create.d.ts +0 -5
|
@@ -12,6 +12,12 @@ class LocalDevWebsocketServer {
|
|
|
12
12
|
_websocket;
|
|
13
13
|
debug;
|
|
14
14
|
localDevProcess;
|
|
15
|
+
ALLOWED_ORIGINS = [
|
|
16
|
+
'https://hubspot.com',
|
|
17
|
+
'https://hubspotqa.com',
|
|
18
|
+
'https://local.hubspot.com',
|
|
19
|
+
'https://local.hubspotqa.com',
|
|
20
|
+
];
|
|
15
21
|
constructor(localDevProcess, debug) {
|
|
16
22
|
this.localDevProcess = localDevProcess;
|
|
17
23
|
this.debug = debug;
|
|
@@ -35,6 +41,19 @@ class LocalDevWebsocketServer {
|
|
|
35
41
|
sendMessage(message) {
|
|
36
42
|
this.websocket().send(JSON.stringify(message));
|
|
37
43
|
}
|
|
44
|
+
async handleUpload() {
|
|
45
|
+
const uploadSuccess = await this.localDevProcess.uploadProject();
|
|
46
|
+
if (uploadSuccess) {
|
|
47
|
+
this.sendMessage({
|
|
48
|
+
type: constants_1.LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_SUCCESS,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.sendMessage({
|
|
53
|
+
type: constants_1.LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_FAILURE,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
38
57
|
setupMessageHandlers() {
|
|
39
58
|
this.websocket().on('message', data => {
|
|
40
59
|
try {
|
|
@@ -44,12 +63,8 @@ class LocalDevWebsocketServer {
|
|
|
44
63
|
return;
|
|
45
64
|
}
|
|
46
65
|
switch (message.type) {
|
|
47
|
-
case constants_1.
|
|
48
|
-
this.
|
|
49
|
-
break;
|
|
50
|
-
case constants_1.LOCAL_DEV_UI_WEBSOCKET_MESSAGE_TYPES.INSTALL_DEPS:
|
|
51
|
-
break;
|
|
52
|
-
case constants_1.LOCAL_DEV_UI_WEBSOCKET_MESSAGE_TYPES.APP_INSTALLED:
|
|
66
|
+
case constants_1.LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.UPLOAD:
|
|
67
|
+
this.handleUpload();
|
|
53
68
|
break;
|
|
54
69
|
default:
|
|
55
70
|
this.logError(en_1.lib.LocalDevWebsocketServer.errors.unknownMessageType(message.type));
|
|
@@ -60,13 +75,30 @@ class LocalDevWebsocketServer {
|
|
|
60
75
|
}
|
|
61
76
|
});
|
|
62
77
|
}
|
|
78
|
+
sendProjectData() {
|
|
79
|
+
this.sendMessage({
|
|
80
|
+
type: constants_1.LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPDATE_PROJECT_DATA,
|
|
81
|
+
data: {
|
|
82
|
+
projectName: this.localDevProcess.projectName,
|
|
83
|
+
projectId: this.localDevProcess.projectId,
|
|
84
|
+
targetProjectAccountId: this.localDevProcess.targetProjectAccountId,
|
|
85
|
+
targetTestingAccountId: this.localDevProcess.targetTestingAccountId,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
63
89
|
setupStateListeners() {
|
|
64
90
|
this.localDevProcess.addStateListener('projectNodes', nodes => {
|
|
65
91
|
this.sendMessage({
|
|
66
|
-
type: constants_1.
|
|
92
|
+
type: constants_1.LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPDATE_PROJECT_NODES,
|
|
67
93
|
data: nodes,
|
|
68
94
|
});
|
|
69
|
-
});
|
|
95
|
+
}, true);
|
|
96
|
+
this.localDevProcess.addStateListener('appData', appData => {
|
|
97
|
+
this.sendMessage({
|
|
98
|
+
type: constants_1.LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPDATE_APP_DATA,
|
|
99
|
+
data: appData,
|
|
100
|
+
});
|
|
101
|
+
}, true);
|
|
70
102
|
}
|
|
71
103
|
async start() {
|
|
72
104
|
const portManagerIsRunning = await (0, portManager_1.isPortManagerServerRunning)();
|
|
@@ -77,10 +109,17 @@ class LocalDevWebsocketServer {
|
|
|
77
109
|
const port = portData[SERVER_INSTANCE_ID];
|
|
78
110
|
this.server = new ws_1.WebSocketServer({ port });
|
|
79
111
|
this.log(en_1.lib.LocalDevWebsocketServer.logs.startup(port));
|
|
80
|
-
this.server.on('connection', ws => {
|
|
112
|
+
this.server.on('connection', (ws, req) => {
|
|
113
|
+
const origin = req.headers.origin;
|
|
114
|
+
if (!origin || !this.ALLOWED_ORIGINS.includes(origin)) {
|
|
115
|
+
ws.close(1008, en_1.lib.LocalDevWebsocketServer.errors.originNotAllowed(origin));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
81
118
|
this._websocket = ws;
|
|
119
|
+
this.sendProjectData();
|
|
82
120
|
this.setupMessageHandlers();
|
|
83
121
|
this.setupStateListeners();
|
|
122
|
+
this.localDevProcess.sendDevServerMessage(constants_1.LOCAL_DEV_SERVER_MESSAGE_TYPES.WEBSOCKET_SERVER_CONNECTED);
|
|
84
123
|
});
|
|
85
124
|
}
|
|
86
125
|
shutdown() {
|
package/lib/projects/upload.js
CHANGED
|
@@ -19,6 +19,7 @@ const node_util_1 = __importDefault(require("node:util"));
|
|
|
19
19
|
const en_1 = require("../../lang/en");
|
|
20
20
|
const ensureProjectExists_1 = require("./ensureProjectExists");
|
|
21
21
|
const logger_1 = require("../ui/logger");
|
|
22
|
+
const buildAndDeploy_1 = require("./buildAndDeploy");
|
|
22
23
|
async function uploadProjectFiles(accountId, projectName, filePath, uploadMessage, platformVersion, intermediateRepresentation) {
|
|
23
24
|
SpinniesManager_1.default.init({});
|
|
24
25
|
const accountIdentifier = (0, ui_1.uiAccountDescription)(accountId);
|
|
@@ -53,6 +54,11 @@ async function handleProjectUpload({ accountId, projectConfig, projectDir, callb
|
|
|
53
54
|
logger_1.uiLogger.log(en_1.lib.projectUpload.handleProjectUpload.emptySource(projectConfig.srcDir));
|
|
54
55
|
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
55
56
|
}
|
|
57
|
+
const hasHsMetaFiles = await (0, project_parsing_lib_1.projectContainsHsMetaFiles)(srcDir);
|
|
58
|
+
if (!(0, buildAndDeploy_1.useV3Api)(projectConfig.platformVersion) && hasHsMetaFiles) {
|
|
59
|
+
logger_1.uiLogger.error(en_1.lib.projectUpload.wrongPlatformVersionMetaFiles);
|
|
60
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
61
|
+
}
|
|
56
62
|
const tempFile = tmp_1.default.fileSync({ postfix: '.zip' });
|
|
57
63
|
logger_1.uiLogger.debug(en_1.lib.projectUpload.handleProjectUpload.compressing(tempFile.name));
|
|
58
64
|
const output = fs_extra_1.default.createWriteStream(tempFile.name);
|
|
@@ -1,19 +1,28 @@
|
|
|
1
|
-
import { ProjectTemplate } from '../../types/Projects';
|
|
2
|
-
type
|
|
1
|
+
import { ComponentTemplate, ComponentTemplateChoice, ProjectTemplate } from '../../types/Projects';
|
|
2
|
+
export type CreateProjectPromptResponse = {
|
|
3
|
+
name: string;
|
|
4
|
+
dest: string;
|
|
5
|
+
projectTemplate?: ProjectTemplate;
|
|
6
|
+
componentTemplates?: ComponentTemplate[];
|
|
7
|
+
};
|
|
8
|
+
type CreateProjectPromptResponseProjectTemplate = {
|
|
3
9
|
name: string;
|
|
4
10
|
dest: string;
|
|
5
11
|
projectTemplate: ProjectTemplate;
|
|
12
|
+
componentTemplates: undefined;
|
|
6
13
|
};
|
|
7
|
-
type
|
|
14
|
+
type CreateProjectPromptResponseComponentTemplates = {
|
|
8
15
|
name: string;
|
|
9
16
|
dest: string;
|
|
10
17
|
projectTemplate?: undefined;
|
|
18
|
+
componentTemplates?: ComponentTemplate[];
|
|
11
19
|
};
|
|
12
20
|
type PromptOptionsArg = {
|
|
13
21
|
name?: string;
|
|
14
22
|
dest?: string;
|
|
15
23
|
template?: string;
|
|
24
|
+
features?: string[];
|
|
16
25
|
};
|
|
17
|
-
export declare function createProjectPrompt(promptOptions: PromptOptionsArg, projectTemplates
|
|
18
|
-
export declare function createProjectPrompt(promptOptions: PromptOptionsArg, projectTemplates?: undefined): Promise<
|
|
26
|
+
export declare function createProjectPrompt(promptOptions: PromptOptionsArg, projectTemplates?: ProjectTemplate[], componentTemplates?: undefined): Promise<CreateProjectPromptResponseProjectTemplate>;
|
|
27
|
+
export declare function createProjectPrompt(promptOptions: PromptOptionsArg, projectTemplates?: undefined, componentTemplates?: ComponentTemplateChoice[]): Promise<CreateProjectPromptResponseComponentTemplates>;
|
|
19
28
|
export {};
|
|
@@ -8,43 +8,58 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
10
10
|
const promptUtils_1 = require("./promptUtils");
|
|
11
|
-
const lang_1 = require("../lang");
|
|
12
11
|
const constants_1 = require("../constants");
|
|
12
|
+
const en_1 = require("../../lang/en");
|
|
13
13
|
function validateProjectDirectory(input) {
|
|
14
14
|
if (!input) {
|
|
15
|
-
return
|
|
15
|
+
return en_1.lib.prompts.createProjectPrompt.errors.destRequired;
|
|
16
16
|
}
|
|
17
17
|
if (fs_1.default.existsSync(path_1.default.resolve((0, path_2.getCwd)(), path_1.default.join(input, constants_1.PROJECT_CONFIG_FILE)))) {
|
|
18
|
-
return
|
|
18
|
+
return en_1.lib.prompts.createProjectPrompt.errors.invalidDest;
|
|
19
19
|
}
|
|
20
20
|
if (!(0, path_2.isValidPath)(input)) {
|
|
21
|
-
return
|
|
21
|
+
return en_1.lib.prompts.createProjectPrompt.errors.invalidCharacters;
|
|
22
22
|
}
|
|
23
23
|
return true;
|
|
24
24
|
}
|
|
25
25
|
function findTemplateByNameOrLabel(projectTemplates, templateNameOrLabel) {
|
|
26
26
|
return projectTemplates.find(t => t.name === templateNameOrLabel || t.label === templateNameOrLabel);
|
|
27
27
|
}
|
|
28
|
-
async function createProjectPrompt(promptOptions, projectTemplates) {
|
|
28
|
+
async function createProjectPrompt(promptOptions, projectTemplates, componentTemplates) {
|
|
29
29
|
const createProjectFromTemplate = !!projectTemplates && projectTemplates.length > 0;
|
|
30
|
+
const createProjectFromComponents = Array.isArray(componentTemplates) && componentTemplates?.length > 0;
|
|
31
|
+
const selectedComponents = [];
|
|
32
|
+
if (createProjectFromComponents && promptOptions.features) {
|
|
33
|
+
componentTemplates.forEach(template => {
|
|
34
|
+
if (!template.value) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (promptOptions.features?.includes(template.value.type)) {
|
|
38
|
+
if (template.disabled) {
|
|
39
|
+
throw new Error(`Cannot create project with template '${template.value.type}'. Reasons: ${template.disabled}`);
|
|
40
|
+
}
|
|
41
|
+
selectedComponents.push(template.value);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
30
45
|
const providedTemplateIsValid = createProjectFromTemplate &&
|
|
31
46
|
!!promptOptions.template &&
|
|
32
47
|
!!findTemplateByNameOrLabel(projectTemplates, promptOptions.template);
|
|
33
48
|
const result = await (0, promptUtils_1.promptUser)([
|
|
34
49
|
{
|
|
35
50
|
name: 'name',
|
|
36
|
-
message:
|
|
51
|
+
message: en_1.lib.prompts.createProjectPrompt.enterName,
|
|
37
52
|
when: !promptOptions.name,
|
|
38
53
|
validate: (input) => {
|
|
39
54
|
if (!input) {
|
|
40
|
-
return
|
|
55
|
+
return en_1.lib.prompts.createProjectPrompt.errors.nameRequired;
|
|
41
56
|
}
|
|
42
57
|
return true;
|
|
43
58
|
},
|
|
44
59
|
},
|
|
45
60
|
{
|
|
46
61
|
name: 'dest',
|
|
47
|
-
message:
|
|
62
|
+
message: en_1.lib.prompts.createProjectPrompt.enterDest,
|
|
48
63
|
when: !promptOptions.dest,
|
|
49
64
|
default: answers => {
|
|
50
65
|
const projectName = (0, path_2.sanitizeFileName)(promptOptions.name || answers.name);
|
|
@@ -59,10 +74,8 @@ async function createProjectPrompt(promptOptions, projectTemplates) {
|
|
|
59
74
|
name: 'projectTemplate',
|
|
60
75
|
message: () => {
|
|
61
76
|
return promptOptions.template && !providedTemplateIsValid
|
|
62
|
-
?
|
|
63
|
-
|
|
64
|
-
})
|
|
65
|
-
: (0, lang_1.i18n)(`lib.prompts.createProjectPrompt.selectTemplate`);
|
|
77
|
+
? en_1.lib.prompts.createProjectPrompt.errors.invalidTemplate(promptOptions.template)
|
|
78
|
+
: en_1.lib.prompts.createProjectPrompt.selectTemplate;
|
|
66
79
|
},
|
|
67
80
|
when: createProjectFromTemplate && !providedTemplateIsValid,
|
|
68
81
|
type: 'list',
|
|
@@ -75,6 +88,13 @@ async function createProjectPrompt(promptOptions, projectTemplates) {
|
|
|
75
88
|
})
|
|
76
89
|
: undefined,
|
|
77
90
|
},
|
|
91
|
+
{
|
|
92
|
+
name: 'componentTemplates',
|
|
93
|
+
message: '[--features] Which features would you like your app to include?',
|
|
94
|
+
when: createProjectFromComponents && selectedComponents.length === 0,
|
|
95
|
+
type: 'checkbox',
|
|
96
|
+
choices: componentTemplates,
|
|
97
|
+
},
|
|
78
98
|
]);
|
|
79
99
|
if (!result.name) {
|
|
80
100
|
result.name = promptOptions.name;
|
|
@@ -82,12 +102,15 @@ async function createProjectPrompt(promptOptions, projectTemplates) {
|
|
|
82
102
|
if (!result.dest) {
|
|
83
103
|
result.dest = promptOptions.dest;
|
|
84
104
|
}
|
|
105
|
+
if (!result.componentTemplates) {
|
|
106
|
+
result.componentTemplates = selectedComponents;
|
|
107
|
+
}
|
|
85
108
|
if (providedTemplateIsValid) {
|
|
86
109
|
result.projectTemplate = findTemplateByNameOrLabel(projectTemplates, promptOptions.template);
|
|
87
110
|
}
|
|
88
111
|
if (projectTemplates && projectTemplates.length > 0) {
|
|
89
112
|
if (!result.projectTemplate) {
|
|
90
|
-
throw new Error(
|
|
113
|
+
throw new Error(en_1.lib.prompts.createProjectPrompt.errors.projectTemplateRequired);
|
|
91
114
|
}
|
|
92
115
|
return result;
|
|
93
116
|
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { ComponentTemplate } from '../../types/Projects';
|
|
1
|
+
import { ComponentTemplate, ComponentTemplateChoice } from '../../types/Projects';
|
|
2
2
|
type ProjectAddPromptResponse = {
|
|
3
3
|
componentTemplate: ComponentTemplate;
|
|
4
4
|
name: string;
|
|
5
5
|
};
|
|
6
|
+
type ProjectAddPromptResponseV3 = {
|
|
7
|
+
componentTemplate: ComponentTemplate[];
|
|
8
|
+
};
|
|
6
9
|
export declare function projectAddPrompt(components: ComponentTemplate[], promptOptions?: {
|
|
7
10
|
name?: string;
|
|
8
11
|
type?: string;
|
|
9
12
|
}): Promise<ProjectAddPromptResponse>;
|
|
13
|
+
export declare function projectAddPromptV3(components: ComponentTemplateChoice[], selectedFeatures: string[] | undefined): Promise<ProjectAddPromptResponseV3>;
|
|
10
14
|
export {};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.projectAddPrompt = projectAddPrompt;
|
|
4
|
+
exports.projectAddPromptV3 = projectAddPromptV3;
|
|
4
5
|
const promptUtils_1 = require("./promptUtils");
|
|
5
|
-
const
|
|
6
|
+
const en_1 = require("../../lang/en");
|
|
6
7
|
function findComponentByPathOrLabel(components, componentPathOrLabel) {
|
|
7
8
|
return components.find(c => c.path === componentPathOrLabel || c.label === componentPathOrLabel);
|
|
8
9
|
}
|
|
@@ -14,10 +15,8 @@ async function projectAddPrompt(components, promptOptions = {}) {
|
|
|
14
15
|
name: 'componentTemplate',
|
|
15
16
|
message: () => {
|
|
16
17
|
return promptOptions.type && !providedTypeIsValid
|
|
17
|
-
?
|
|
18
|
-
|
|
19
|
-
})
|
|
20
|
-
: (0, lang_1.i18n)(`lib.prompts.projectAddPrompt.selectType`);
|
|
18
|
+
? en_1.lib.prompts.projectAddPrompt.errors.invalidType(promptOptions.type)
|
|
19
|
+
: en_1.lib.prompts.projectAddPrompt.selectType;
|
|
21
20
|
},
|
|
22
21
|
when: !providedTypeIsValid,
|
|
23
22
|
type: 'list',
|
|
@@ -30,11 +29,11 @@ async function projectAddPrompt(components, promptOptions = {}) {
|
|
|
30
29
|
},
|
|
31
30
|
{
|
|
32
31
|
name: 'name',
|
|
33
|
-
message:
|
|
32
|
+
message: en_1.lib.prompts.projectAddPrompt.enterName,
|
|
34
33
|
when: !promptOptions.name,
|
|
35
34
|
validate: (input) => {
|
|
36
35
|
if (!input) {
|
|
37
|
-
return
|
|
36
|
+
return en_1.lib.prompts.projectAddPrompt.errors.nameRequired;
|
|
38
37
|
}
|
|
39
38
|
return true;
|
|
40
39
|
},
|
|
@@ -48,3 +47,32 @@ async function projectAddPrompt(components, promptOptions = {}) {
|
|
|
48
47
|
}
|
|
49
48
|
return result;
|
|
50
49
|
}
|
|
50
|
+
async function projectAddPromptV3(components, selectedFeatures) {
|
|
51
|
+
const selectedComponents = [];
|
|
52
|
+
if (selectedFeatures) {
|
|
53
|
+
components.forEach(template => {
|
|
54
|
+
if (!template.value) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (selectedFeatures?.includes(template.value.type)) {
|
|
58
|
+
if (template.disabled) {
|
|
59
|
+
throw new Error(en_1.lib.prompts.projectAddPrompt.errors.cannotAddFeature(template.value.type, template.disabled));
|
|
60
|
+
}
|
|
61
|
+
selectedComponents.push(template.value);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const result = await (0, promptUtils_1.promptUser)([
|
|
66
|
+
{
|
|
67
|
+
name: 'componentTemplate',
|
|
68
|
+
message: en_1.lib.prompts.projectAddPrompt.selectType,
|
|
69
|
+
when: selectedComponents.length === 0,
|
|
70
|
+
type: 'checkbox',
|
|
71
|
+
choices: components,
|
|
72
|
+
},
|
|
73
|
+
]);
|
|
74
|
+
if (!result.componentTemplate) {
|
|
75
|
+
result.componentTemplate = selectedComponents;
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PromptConfig, GenericPromptResponse, PromptWhen, PromptChoices } from '../../types/Prompts';
|
|
2
|
-
export declare const Separator: any;
|
|
3
2
|
export declare function promptUser<T extends GenericPromptResponse>(config: PromptConfig<T> | PromptConfig<T>[]): Promise<T>;
|
|
4
3
|
export declare function confirmPrompt(message: string, options?: {
|
|
5
4
|
defaultAnswer?: boolean;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Separator = void 0;
|
|
4
3
|
exports.promptUser = promptUser;
|
|
5
4
|
exports.confirmPrompt = confirmPrompt;
|
|
6
5
|
exports.listPrompt = listPrompt;
|
|
7
6
|
exports.inputPrompt = inputPrompt;
|
|
8
7
|
const inquirer = require('inquirer');
|
|
9
8
|
const promptModule = inquirer.createPromptModule();
|
|
10
|
-
exports.Separator = new inquirer.Separator();
|
|
11
9
|
function promptUser(config) {
|
|
12
10
|
return promptModule(config);
|
|
13
11
|
}
|
|
@@ -4,6 +4,7 @@ exports.setAsDefaultAccountPrompt = setAsDefaultAccountPrompt;
|
|
|
4
4
|
const config_1 = require("@hubspot/local-dev-lib/config");
|
|
5
5
|
const promptUtils_1 = require("./promptUtils");
|
|
6
6
|
const lang_1 = require("../lang");
|
|
7
|
+
const logger_1 = require("../ui/logger");
|
|
7
8
|
async function setAsDefaultAccountPrompt(accountName) {
|
|
8
9
|
// Accounts for deprecated and new config
|
|
9
10
|
const defaultAccount = (0, config_1.getConfigDefaultAccount)();
|
|
@@ -15,8 +16,17 @@ async function setAsDefaultAccountPrompt(accountName) {
|
|
|
15
16
|
message: (0, lang_1.i18n)(`lib.prompts.setAsDefaultAccountPrompt.setAsDefaultAccountMessage`),
|
|
16
17
|
},
|
|
17
18
|
]);
|
|
19
|
+
logger_1.uiLogger.log('');
|
|
18
20
|
if (setAsDefault) {
|
|
19
21
|
(0, config_1.updateDefaultAccount)(accountName);
|
|
22
|
+
logger_1.uiLogger.success((0, lang_1.i18n)('lib.prompts.setAsDefaultAccountPrompt.setAsDefaultAccount', {
|
|
23
|
+
accountName,
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
logger_1.uiLogger.log((0, lang_1.i18n)('lib.prompts.setAsDefaultAccountPrompt.keepingCurrentDefault', {
|
|
28
|
+
accountName: (0, config_1.getConfigDefaultAccount)(),
|
|
29
|
+
}));
|
|
20
30
|
}
|
|
21
31
|
return setAsDefault;
|
|
22
32
|
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "7.7.
|
|
3
|
+
"version": "7.7.2-experimental.0",
|
|
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
|
"dependencies": {
|
|
8
|
-
"@hubspot/local-dev-lib": "
|
|
9
|
-
"@hubspot/project-parsing-lib": "0.
|
|
8
|
+
"@hubspot/local-dev-lib": "3.7.1",
|
|
9
|
+
"@hubspot/project-parsing-lib": "0.3.1-beta.0",
|
|
10
10
|
"@hubspot/serverless-dev-runtime": "7.0.2",
|
|
11
11
|
"@hubspot/theme-preview-dev-server": "0.0.10",
|
|
12
|
-
"@hubspot/ui-extensions-dev-server": "0.
|
|
12
|
+
"@hubspot/ui-extensions-dev-server": "0.9.2",
|
|
13
13
|
"archiver": "7.0.1",
|
|
14
14
|
"boxen": "8.0.1",
|
|
15
15
|
"chalk": "4.1.2",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@types/yargs": "^17.0.33",
|
|
47
47
|
"@typescript-eslint/eslint-plugin": "^8.30.1",
|
|
48
48
|
"@typescript-eslint/parser": "^8.11.0",
|
|
49
|
-
"axios": "^1.7.
|
|
49
|
+
"axios": "^1.7.4",
|
|
50
50
|
"eslint": "^8.56.0",
|
|
51
51
|
"eslint-plugin-import": "^2.31.0",
|
|
52
52
|
"husky": "^4.3.8",
|
|
@@ -80,7 +80,8 @@
|
|
|
80
80
|
"release": "yarn ts-node ./scripts/release.ts release",
|
|
81
81
|
"hs": "yarn build && node ./dist/bin/hs",
|
|
82
82
|
"hs-debug": "yarn build && NODE_DEBUG=http* node --inspect-brk ./dist/bin/hs",
|
|
83
|
-
"update-ldl": "yarn add --exact @hubspot/local-dev-lib@latest"
|
|
83
|
+
"update-ldl": "yarn add --exact @hubspot/local-dev-lib@latest",
|
|
84
|
+
"view-unreleased-changes": "node ./scripts/unreleasedChanges.js"
|
|
84
85
|
},
|
|
85
86
|
"lint-staged": {
|
|
86
87
|
"**/*.{js,ts,scss,css}": [
|
package/types/LocalDev.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types';
|
|
2
2
|
import { Build } from '@hubspot/local-dev-lib/types/Build';
|
|
3
3
|
import { Environment } from '@hubspot/local-dev-lib/types/Config';
|
|
4
|
+
import { ValueOf } from '@hubspot/local-dev-lib/types/Utils';
|
|
4
5
|
import { ProjectConfig } from './Projects';
|
|
5
6
|
import LocalDevState from '../lib/projects/localDev/LocalDevState';
|
|
7
|
+
import { APP_INSTALLATION_STATES, LOCAL_DEV_SERVER_MESSAGE_TYPES } from '../lib/constants';
|
|
6
8
|
export type LocalDevStateConstructorOptions = {
|
|
7
9
|
targetProjectAccountId: number;
|
|
8
10
|
targetTestingAccountId: number;
|
|
9
11
|
projectConfig: ProjectConfig;
|
|
10
12
|
projectDir: string;
|
|
11
13
|
projectId: number;
|
|
14
|
+
projectName: string;
|
|
12
15
|
debug?: boolean;
|
|
13
16
|
deployedBuild?: Build;
|
|
14
17
|
isGithubLinked: boolean;
|
|
@@ -19,6 +22,13 @@ export type LocalDevStateConstructorOptions = {
|
|
|
19
22
|
};
|
|
20
23
|
export type LocalDevWebsocketMessage = {
|
|
21
24
|
type: string;
|
|
22
|
-
data
|
|
25
|
+
data?: unknown;
|
|
23
26
|
};
|
|
24
27
|
export type LocalDevStateListener<K extends keyof LocalDevState> = (value: LocalDevState[K]) => void;
|
|
28
|
+
export type AppLocalDevData = {
|
|
29
|
+
id: number;
|
|
30
|
+
clientId: string;
|
|
31
|
+
name: string;
|
|
32
|
+
installationState: ValueOf<typeof APP_INSTALLATION_STATES>;
|
|
33
|
+
};
|
|
34
|
+
export type LocalDevServerMessage = ValueOf<typeof LOCAL_DEV_SERVER_MESSAGE_TYPES>;
|
package/types/Projects.d.ts
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import { Build, SubbuildStatus } from '@hubspot/local-dev-lib/types/Build';
|
|
2
2
|
import { Deploy, SubdeployStatus } from '@hubspot/local-dev-lib/types/Deploy';
|
|
3
|
+
import { appComponent, marketplaceDistribution, oAuth, privateDistribution, staticAuth } from '../lib/constants';
|
|
3
4
|
export type ProjectTemplate = {
|
|
4
5
|
name: string;
|
|
5
6
|
label: string;
|
|
6
7
|
path: string;
|
|
7
|
-
insertPath: string;
|
|
8
8
|
};
|
|
9
9
|
export type ComponentTemplate = {
|
|
10
10
|
path: string;
|
|
11
11
|
label: string;
|
|
12
|
-
|
|
12
|
+
type: string;
|
|
13
|
+
parentComponent?: string;
|
|
14
|
+
supportedAuthTypes?: string[];
|
|
15
|
+
supportedDistributions?: string[];
|
|
16
|
+
};
|
|
17
|
+
export type ComponentTemplateChoice = {
|
|
18
|
+
name: string;
|
|
19
|
+
value: ComponentTemplate;
|
|
20
|
+
disabled?: string | boolean;
|
|
13
21
|
};
|
|
14
22
|
export type ProjectConfig = {
|
|
15
23
|
name: string;
|
|
@@ -32,9 +40,18 @@ export type ProjectPollStatusFunctionText = {
|
|
|
32
40
|
TYPE_KEY: string;
|
|
33
41
|
SUBTASK_NAME_KEY: string;
|
|
34
42
|
};
|
|
43
|
+
export type ParentComponent = {
|
|
44
|
+
label: string;
|
|
45
|
+
type: typeof appComponent;
|
|
46
|
+
authType: typeof staticAuth | typeof oAuth;
|
|
47
|
+
distribution: typeof privateDistribution | typeof marketplaceDistribution;
|
|
48
|
+
path: string;
|
|
49
|
+
};
|
|
35
50
|
export type ProjectTemplateRepoConfig = {
|
|
36
51
|
projects?: ProjectTemplate[];
|
|
37
52
|
components?: ComponentTemplate[];
|
|
53
|
+
defaultFiles?: string;
|
|
54
|
+
parentComponents?: ParentComponent[];
|
|
38
55
|
};
|
|
39
56
|
export type ProjectPollResult = {
|
|
40
57
|
succeeded: boolean;
|
package/types/Yargs.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ export type StringArgType = Options & {
|
|
|
26
26
|
};
|
|
27
27
|
export type ProjectDevArgs = CommonArgs & ConfigArgs & EnvironmentArgs & {
|
|
28
28
|
profile?: string;
|
|
29
|
+
testingAccount?: string | number;
|
|
30
|
+
projectAccount?: string | number;
|
|
29
31
|
};
|
|
30
32
|
export type TestingArgs = {
|
|
31
33
|
qa?: boolean;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { CommonArgs, YargsCommandModule } from '../../types/Yargs';
|
|
2
|
-
type CreateTestAccountArgs = CommonArgs & {
|
|
3
|
-
name: string;
|
|
4
|
-
tiers: string[];
|
|
5
|
-
};
|
|
6
|
-
declare const createTestAccountCommand: YargsCommandModule<unknown, CreateTestAccountArgs>;
|
|
7
|
-
export default createTestAccountCommand;
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const developerTestAccounts_1 = require("@hubspot/local-dev-lib/api/developerTestAccounts");
|
|
4
|
-
const yargsUtils_1 = require("../../lib/yargsUtils");
|
|
5
|
-
const promptUtils_1 = require("../../lib/prompts/promptUtils");
|
|
6
|
-
const exitCodes_1 = require("../../lib/enums/exitCodes");
|
|
7
|
-
const logger_1 = require("../../lib/ui/logger");
|
|
8
|
-
const command = 'create [name]';
|
|
9
|
-
const describe = 'Create a test account';
|
|
10
|
-
const hubs = {
|
|
11
|
-
MARKETING: 'marketingLevel',
|
|
12
|
-
OPS: 'opsLevel',
|
|
13
|
-
SERVICE: 'serviceLevel',
|
|
14
|
-
SALES: 'salesLevel',
|
|
15
|
-
CONTENT: 'contentLevel',
|
|
16
|
-
};
|
|
17
|
-
const TEST_ACCOUNT_TIERS = [
|
|
18
|
-
{ name: 'Marketing STARTER', value: 'MARKETING:STARTER' },
|
|
19
|
-
{ name: 'Marketing PRO', value: 'MARKETING:PRO' },
|
|
20
|
-
{ name: 'Marketing ENTERPRISE', value: 'MARKETING:ENTERPRISE' },
|
|
21
|
-
promptUtils_1.Separator,
|
|
22
|
-
{ name: 'Ops STARTER', value: 'OPS:STARTER' },
|
|
23
|
-
{ name: 'Ops PRO', value: 'OPS:PRO' },
|
|
24
|
-
{ name: 'Ops ENTERPRISE', value: 'OPS:ENTERPRISE' },
|
|
25
|
-
promptUtils_1.Separator,
|
|
26
|
-
{ name: 'Service STARTER', value: 'SERVICE:STARTER' },
|
|
27
|
-
{ name: 'Service PRO', value: 'SERVICE:PRO' },
|
|
28
|
-
{ name: 'Service ENTERPRISE', value: 'SERVICE:ENTERPRISE' },
|
|
29
|
-
promptUtils_1.Separator,
|
|
30
|
-
{ name: 'Sales STARTER', value: 'SALES:STARTER' },
|
|
31
|
-
{ name: 'Sales PRO', value: 'SALES:PRO' },
|
|
32
|
-
{ name: 'Sales ENTERPRISE', value: 'SALES:ENTERPRISE' },
|
|
33
|
-
promptUtils_1.Separator,
|
|
34
|
-
{ name: 'Content STARTER', value: 'CONTENT:STARTER' },
|
|
35
|
-
{ name: 'Content PRO', value: 'CONTENT:PRO' },
|
|
36
|
-
{ name: 'Content ENTERPRISE', value: 'CONTENT:ENTERPRISE' },
|
|
37
|
-
promptUtils_1.Separator,
|
|
38
|
-
];
|
|
39
|
-
async function handler(args) {
|
|
40
|
-
const { derivedAccountId, name, tiers } = args;
|
|
41
|
-
// trackCommandUsage('test-account-create', {}, derivedAccountId);
|
|
42
|
-
let accountName = name;
|
|
43
|
-
let accountLevelsArray = tiers;
|
|
44
|
-
if (!name) {
|
|
45
|
-
const namePromptResult = await (0, promptUtils_1.promptUser)({
|
|
46
|
-
name: 'accountName',
|
|
47
|
-
message: 'What is the name of the test account?',
|
|
48
|
-
type: 'input',
|
|
49
|
-
});
|
|
50
|
-
accountName = namePromptResult.accountName;
|
|
51
|
-
}
|
|
52
|
-
if (!accountLevelsArray) {
|
|
53
|
-
const accountLevelsPromptResult = await (0, promptUtils_1.promptUser)({
|
|
54
|
-
name: 'testAccountLevels',
|
|
55
|
-
message: '[--tiers] Which tiers should the test account have?',
|
|
56
|
-
type: 'checkbox',
|
|
57
|
-
choices: TEST_ACCOUNT_TIERS,
|
|
58
|
-
validate: choices => {
|
|
59
|
-
if (choices?.length > 1) {
|
|
60
|
-
const hubMap = {};
|
|
61
|
-
for (const choice of choices) {
|
|
62
|
-
const hub = choice.split(':')[0];
|
|
63
|
-
if (hubMap[hub]) {
|
|
64
|
-
return 'Cannot have more than one tier per hub';
|
|
65
|
-
}
|
|
66
|
-
hubMap[hub] = true;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return true;
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
accountLevelsArray = accountLevelsPromptResult.testAccountLevels;
|
|
73
|
-
}
|
|
74
|
-
const accountLevels = accountLevelsArray.reduce((acc, level) => {
|
|
75
|
-
const parts = level.split(':');
|
|
76
|
-
const hubName = hubs[parts[0]];
|
|
77
|
-
const hubTier = parts[1];
|
|
78
|
-
acc[hubName] = hubTier;
|
|
79
|
-
return acc;
|
|
80
|
-
}, {});
|
|
81
|
-
try {
|
|
82
|
-
const { data } = await (0, developerTestAccounts_1.createDeveloperTestAccount)(derivedAccountId, accountName, true, accountLevels);
|
|
83
|
-
// @ts-expect-error - testPortalId is not typed
|
|
84
|
-
logger_1.uiLogger.log(`Test account created: ${data.testPortalId}`);
|
|
85
|
-
}
|
|
86
|
-
catch (err) {
|
|
87
|
-
logger_1.uiLogger.error('Failed to create test account');
|
|
88
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
89
|
-
}
|
|
90
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
91
|
-
}
|
|
92
|
-
function createTestAccountBuilder(yargs) {
|
|
93
|
-
yargs.positional('name', {
|
|
94
|
-
type: 'string',
|
|
95
|
-
description: 'The name of the test account',
|
|
96
|
-
});
|
|
97
|
-
yargs.option('tiers', {
|
|
98
|
-
type: 'array',
|
|
99
|
-
description: 'The tiers of the test account',
|
|
100
|
-
});
|
|
101
|
-
yargs.example([
|
|
102
|
-
[
|
|
103
|
-
'$0 create my-account --tiers MARKETING:STARTER OPS:PRO',
|
|
104
|
-
'Create a test account with the name "my-account" and the tiers "Marketing - STARTER, OPS - PRO"',
|
|
105
|
-
],
|
|
106
|
-
]);
|
|
107
|
-
return yargs;
|
|
108
|
-
}
|
|
109
|
-
const builder = (0, yargsUtils_1.makeYargsBuilder)(createTestAccountBuilder, command, describe, {
|
|
110
|
-
useGlobalOptions: true,
|
|
111
|
-
});
|
|
112
|
-
const createTestAccountCommand = {
|
|
113
|
-
command,
|
|
114
|
-
describe,
|
|
115
|
-
handler,
|
|
116
|
-
builder,
|
|
117
|
-
};
|
|
118
|
-
exports.default = createTestAccountCommand;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { CommonArgs, YargsCommandModule } from '../../types/Yargs';
|
|
2
|
-
type DeleteTestAccountArgs = CommonArgs & {
|
|
3
|
-
testAccountId: number;
|
|
4
|
-
};
|
|
5
|
-
declare const deleteTestAccountCommand: YargsCommandModule<unknown, DeleteTestAccountArgs>;
|
|
6
|
-
export default deleteTestAccountCommand;
|