@hubspot/cli 7.6.0-experimental.0 → 7.7.0-experimental.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/bin/cli.js +2 -2
- package/bin/hsmcp.d.ts +2 -0
- package/bin/hsmcp.js +13 -0
- package/commands/project/validate.d.ts +4 -0
- package/commands/project/validate.js +53 -0
- package/commands/project.js +2 -0
- package/commands/setupMcp.d.ts +8 -0
- package/commands/setupMcp.js +229 -0
- package/lang/en.d.ts +51 -0
- package/lang/en.js +51 -0
- package/lib/prompts/promptUtils.d.ts +0 -1
- package/lib/prompts/promptUtils.js +0 -2
- package/mcp-server/index.d.ts +1 -0
- package/mcp-server/index.js +17 -0
- package/mcp-server/mcpLoader.d.ts +5 -0
- package/mcp-server/mcpLoader.js +24 -0
- package/mcp-server/tools/ExplainProjectStructureTool.d.ts +33 -0
- package/mcp-server/tools/ExplainProjectStructureTool.js +266 -0
- package/mcp-server/tools/GenerateAppComponentTool.d.ts +99 -0
- package/mcp-server/tools/GenerateAppComponentTool.js +193 -0
- package/mcp-server/tools/GenerateCardComponentTool.d.ts +74 -0
- package/mcp-server/tools/GenerateCardComponentTool.js +146 -0
- package/mcp-server/tools/GenerateProjectConfigTool.d.ts +32 -0
- package/mcp-server/tools/GenerateProjectConfigTool.js +40 -0
- package/mcp-server/tools/HubSpotCLIHelper.d.ts +24 -0
- package/mcp-server/tools/HubSpotCLIHelper.js +110 -0
- package/mcp-server/tools/UploadProjectTool.d.ts +44 -0
- package/mcp-server/tools/UploadProjectTool.js +153 -0
- package/mcp-server/tools/ValidateProjectTool.d.ts +62 -0
- package/mcp-server/tools/ValidateProjectTool.js +324 -0
- package/package.json +6 -3
- package/commands/testAccount/create.d.ts +0 -7
- package/commands/testAccount/create.js +0 -118
- package/commands/testAccount.d.ts +0 -3
- package/commands/testAccount.js +0 -23
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { MCPTool } from 'mcp-framework';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import HubSpotCLIHelper from './HubSpotCLIHelper.js';
|
|
4
|
+
class ValidateProjectTool extends MCPTool {
|
|
5
|
+
name = 'validateProject';
|
|
6
|
+
description = 'Validates a developer project using the HubSpot CLI and provides guidance for fixing any validation errors';
|
|
7
|
+
cliHelper = new HubSpotCLIHelper();
|
|
8
|
+
schema = {
|
|
9
|
+
autoFix: {
|
|
10
|
+
type: z.boolean().optional(),
|
|
11
|
+
description: 'Whether to attempt automatic fixes for common validation errors. Defaults to false',
|
|
12
|
+
},
|
|
13
|
+
projectPath: {
|
|
14
|
+
type: z.string().optional(),
|
|
15
|
+
description: 'Path to the project directory. Defaults to current directory',
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
async execute(input) {
|
|
19
|
+
// Default to current working directory, which should be where Cursor is running from
|
|
20
|
+
const { autoFix = false, projectPath = process.cwd() } = input;
|
|
21
|
+
try {
|
|
22
|
+
// Step 1: Check if HubSpot CLI is installed
|
|
23
|
+
const cliCheckResult = await this.cliHelper.checkCLIInstallation();
|
|
24
|
+
if (!cliCheckResult.isInstalled) {
|
|
25
|
+
return {
|
|
26
|
+
status: 'cli-not-found',
|
|
27
|
+
error: `Debug info: ${JSON.stringify(cliCheckResult.debugInfo, null, 2)}`,
|
|
28
|
+
message: 'HubSpot CLI not found. Installing...',
|
|
29
|
+
actions: [
|
|
30
|
+
{
|
|
31
|
+
action: 'install-cli',
|
|
32
|
+
command: 'npm install -g @hubspot/cli',
|
|
33
|
+
description: 'Installing HubSpot CLI globally',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
nextSteps: [
|
|
37
|
+
'1. Install HubSpot CLI globally',
|
|
38
|
+
'2. Run project validation again',
|
|
39
|
+
'3. Follow any additional guidance for fixing validation errors',
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// Step 2: Run project validation
|
|
44
|
+
const validationResult = await this.runProjectValidation(projectPath);
|
|
45
|
+
if (validationResult.isValid) {
|
|
46
|
+
return {
|
|
47
|
+
status: 'valid',
|
|
48
|
+
message: '✅ Project validation passed! Your developer project is properly configured.',
|
|
49
|
+
cliVersion: cliCheckResult.version,
|
|
50
|
+
validationOutput: validationResult.output,
|
|
51
|
+
projectStructure: 'All components and configurations follow platform conventions',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// Step 3: Parse validation errors and provide guidance
|
|
55
|
+
const errorAnalysis = this.analyzeValidationErrors(validationResult.errors);
|
|
56
|
+
const suggestions = this.generateFixSuggestions(errorAnalysis);
|
|
57
|
+
const response = {
|
|
58
|
+
status: 'validation-failed',
|
|
59
|
+
message: "❌ Project validation failed. Here's how to fix the issues:",
|
|
60
|
+
cliVersion: cliCheckResult.version,
|
|
61
|
+
validationOutput: validationResult.output,
|
|
62
|
+
errors: validationResult.errors,
|
|
63
|
+
errorAnalysis: errorAnalysis,
|
|
64
|
+
suggestions: suggestions,
|
|
65
|
+
nextSteps: this.generateNextSteps(errorAnalysis, autoFix),
|
|
66
|
+
};
|
|
67
|
+
if (autoFix) {
|
|
68
|
+
response.autoFixActions = this.generateAutoFixActions(errorAnalysis);
|
|
69
|
+
}
|
|
70
|
+
return response;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
74
|
+
return {
|
|
75
|
+
status: 'error',
|
|
76
|
+
message: 'An error occurred during project validation',
|
|
77
|
+
error: errorMessage,
|
|
78
|
+
troubleshooting: [
|
|
79
|
+
"Ensure you're in a valid developer project directory",
|
|
80
|
+
'Check that hsproject.json exists in the project root',
|
|
81
|
+
'Verify HubSpot CLI is properly installed and accessible',
|
|
82
|
+
"Try running 'hs project validate' manually to see detailed output",
|
|
83
|
+
`Attempted project path: ${projectPath}`,
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async runProjectValidation(projectPath) {
|
|
89
|
+
try {
|
|
90
|
+
const result = await this.cliHelper.runProjectCommand('hs project validate', projectPath);
|
|
91
|
+
if (result.success) {
|
|
92
|
+
// Parse the validation output to determine if it passed
|
|
93
|
+
const output = result.output;
|
|
94
|
+
// Check for validation success indicators
|
|
95
|
+
const isValid = output.includes('✅') ||
|
|
96
|
+
output.includes('Project validation passed') ||
|
|
97
|
+
output.includes('valid') ||
|
|
98
|
+
!output.includes('Project validation failed:');
|
|
99
|
+
// Parse structured validation errors if present
|
|
100
|
+
const errors = [];
|
|
101
|
+
if (!isValid && output.includes('Project validation failed:')) {
|
|
102
|
+
errors.push(...this.parseValidationErrors(output));
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
isValid: isValid,
|
|
106
|
+
output: output,
|
|
107
|
+
errors: errors,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// Command failed to run
|
|
112
|
+
const errorMessage = result.error || 'Failed to run project validation';
|
|
113
|
+
const errors = [errorMessage];
|
|
114
|
+
// Add debugging information about directory context
|
|
115
|
+
if (result.output.includes('Unable to locate a project configuration file')) {
|
|
116
|
+
errors.push(`Working directory was: ${projectPath}`);
|
|
117
|
+
errors.push("Make sure you're running this from a directory containing hsproject.json");
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
isValid: false,
|
|
121
|
+
output: result.output || '',
|
|
122
|
+
errors: errors,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown validation error';
|
|
128
|
+
throw new Error(`Failed to run project validation: ${errorMessage}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
runCommand(command) {
|
|
132
|
+
// Delegate to the CLI helper
|
|
133
|
+
return this.cliHelper.runCommand(command);
|
|
134
|
+
}
|
|
135
|
+
parseValidationErrors(output) {
|
|
136
|
+
const errors = [];
|
|
137
|
+
const lines = output.split('\n');
|
|
138
|
+
let currentFile = '';
|
|
139
|
+
let inErrorSection = false;
|
|
140
|
+
for (const line of lines) {
|
|
141
|
+
// Look for file error headers like "Encountered the following errors for src/app/file.json:"
|
|
142
|
+
const fileMatch = line.match(/Encountered the following errors for (.+?):/);
|
|
143
|
+
if (fileMatch) {
|
|
144
|
+
currentFile = fileMatch[1];
|
|
145
|
+
inErrorSection = true;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
// Parse individual error lines (start with tab and dash)
|
|
149
|
+
if (inErrorSection && line.match(/^\s*-\s+/)) {
|
|
150
|
+
const errorText = line.replace(/^\s*-\s+/, '').trim();
|
|
151
|
+
if (errorText) {
|
|
152
|
+
errors.push(`${currentFile}: ${errorText}`);
|
|
153
|
+
}
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
// Handle multi-line errors with additional indentation
|
|
157
|
+
if (inErrorSection && line.match(/^\s{2,}-\s+/)) {
|
|
158
|
+
const errorText = line.replace(/^\s*-\s+/, '').trim();
|
|
159
|
+
if (errorText && errors.length > 0) {
|
|
160
|
+
// Append to the last error as additional context
|
|
161
|
+
errors[errors.length - 1] += `\n ${errorText}`;
|
|
162
|
+
}
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
// Reset when we hit an empty line or new section
|
|
166
|
+
if (line.trim() === '' ||
|
|
167
|
+
(!line.startsWith('\t') && !line.startsWith(' '))) {
|
|
168
|
+
inErrorSection = false;
|
|
169
|
+
currentFile = '';
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return errors;
|
|
173
|
+
}
|
|
174
|
+
analyzeValidationErrors(errors) {
|
|
175
|
+
const analysis = [];
|
|
176
|
+
for (const error of errors) {
|
|
177
|
+
const filePath = error.split(':')[0];
|
|
178
|
+
const errorMessage = error.substring(error.indexOf(':') + 1).trim();
|
|
179
|
+
let category = 'unknown';
|
|
180
|
+
let component = 'unknown';
|
|
181
|
+
let severity = 'error';
|
|
182
|
+
// Extract file information
|
|
183
|
+
if (filePath.includes('hsproject.json')) {
|
|
184
|
+
category = 'project-config';
|
|
185
|
+
component = 'project';
|
|
186
|
+
}
|
|
187
|
+
else if (filePath.includes('-hsmeta.json')) {
|
|
188
|
+
category = 'component-config';
|
|
189
|
+
component = this.extractComponentFromPath(filePath);
|
|
190
|
+
}
|
|
191
|
+
else if (filePath.includes('package.json')) {
|
|
192
|
+
category = 'dependencies';
|
|
193
|
+
component = this.extractComponentFromPath(filePath);
|
|
194
|
+
severity = 'warning';
|
|
195
|
+
}
|
|
196
|
+
// Analyze error message content
|
|
197
|
+
if (errorMessage.includes('Invalid JSON')) {
|
|
198
|
+
category = 'json-syntax';
|
|
199
|
+
}
|
|
200
|
+
else if (errorMessage.includes('Missing required field')) {
|
|
201
|
+
category = 'required-field';
|
|
202
|
+
}
|
|
203
|
+
else if (errorMessage.includes('must NOT have additional properties')) {
|
|
204
|
+
category = 'schema-validation';
|
|
205
|
+
}
|
|
206
|
+
else if (errorMessage.includes('entrypoint')) {
|
|
207
|
+
category = 'entrypoint';
|
|
208
|
+
}
|
|
209
|
+
analysis.push({
|
|
210
|
+
category: category,
|
|
211
|
+
issue: errorMessage,
|
|
212
|
+
severity: severity,
|
|
213
|
+
component: component,
|
|
214
|
+
file: filePath,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return analysis;
|
|
218
|
+
}
|
|
219
|
+
extractComponentFromPath(filePath) {
|
|
220
|
+
// Extract component type from file path like "src/app/cards/my-card-hsmeta.json"
|
|
221
|
+
if (filePath.includes('/app/')) {
|
|
222
|
+
const pathParts = filePath.split('/app/')[1].split('/');
|
|
223
|
+
if (pathParts.length > 1) {
|
|
224
|
+
return pathParts[0]; // e.g., "cards", "functions", etc.
|
|
225
|
+
}
|
|
226
|
+
return 'app';
|
|
227
|
+
}
|
|
228
|
+
// Handle top-level app component files
|
|
229
|
+
if (filePath.includes('-hsmeta.json')) {
|
|
230
|
+
return 'app';
|
|
231
|
+
}
|
|
232
|
+
return 'unknown';
|
|
233
|
+
}
|
|
234
|
+
generateFixSuggestions(errorAnalysis) {
|
|
235
|
+
const suggestions = [];
|
|
236
|
+
for (const error of errorAnalysis) {
|
|
237
|
+
switch (error.category) {
|
|
238
|
+
case 'project-config':
|
|
239
|
+
suggestions.push("Fix hsproject.json: Ensure it contains 'name', 'srcDir', and 'platformVersion' fields", 'Use the generateProjectConfig tool to create a valid hsproject.json file');
|
|
240
|
+
break;
|
|
241
|
+
case 'component-config':
|
|
242
|
+
suggestions.push(`Fix ${error.component} component: Check the *-hsmeta.json file structure`, 'Ensure the component follows the envelope pattern: uid, type, config', `Use the appropriate generate component tool for ${error.component} type`);
|
|
243
|
+
break;
|
|
244
|
+
case 'json-syntax':
|
|
245
|
+
suggestions.push(`Fix JSON syntax error in ${error.file}`, 'Check for missing commas, brackets, or quotes in the JSON file', 'Use a JSON validator to identify the specific syntax issue');
|
|
246
|
+
break;
|
|
247
|
+
case 'required-field':
|
|
248
|
+
suggestions.push(`Add missing required field: ${this.extractFieldFromError(error.issue)}`, `Update ${error.file} to include all required fields`, 'Refer to the platform documentation for required field specifications');
|
|
249
|
+
break;
|
|
250
|
+
case 'schema-validation':
|
|
251
|
+
suggestions.push(`Fix schema validation error in ${error.file}`, 'Remove additional properties that are not allowed', `Check ${error.component} component schema requirements`, 'Ensure all field types match the expected schema');
|
|
252
|
+
break;
|
|
253
|
+
case 'dependencies':
|
|
254
|
+
suggestions.push('Fix package.json: Ensure React and @hubspot/ui-extensions dependencies are present', "Run 'npm install' to install missing dependencies", 'Check that package.json is in the correct component directory');
|
|
255
|
+
break;
|
|
256
|
+
case 'entrypoint':
|
|
257
|
+
suggestions.push('Fix component entrypoint: Ensure the React file exists at the specified path', 'Check that the entrypoint path in *-hsmeta.json matches the actual file location', 'Verify the React component exports properly');
|
|
258
|
+
break;
|
|
259
|
+
default:
|
|
260
|
+
suggestions.push(`Review error in ${error.file || 'project'}: ${error.issue}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return [...new Set(suggestions)]; // Remove duplicates
|
|
264
|
+
}
|
|
265
|
+
extractFieldFromError(errorMessage) {
|
|
266
|
+
// Extract field name from messages like "Missing required field: config.description"
|
|
267
|
+
const match = errorMessage.match(/Missing required field:\s*(.+)/);
|
|
268
|
+
return match ? match[1] : 'unknown field';
|
|
269
|
+
}
|
|
270
|
+
generateNextSteps(errorAnalysis, autoFix) {
|
|
271
|
+
const steps = [];
|
|
272
|
+
if (autoFix) {
|
|
273
|
+
steps.push('1. Review auto-fix actions and apply them');
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
steps.push('1. Review the validation errors and suggestions above');
|
|
277
|
+
}
|
|
278
|
+
const hasProjectConfig = errorAnalysis.some(e => e.category === 'project-config');
|
|
279
|
+
const hasComponentIssues = errorAnalysis.some(e => e.category === 'component-config');
|
|
280
|
+
const hasDependencyIssues = errorAnalysis.some(e => e.category === 'dependencies');
|
|
281
|
+
if (hasProjectConfig) {
|
|
282
|
+
steps.push('2. Fix hsproject.json configuration issues first');
|
|
283
|
+
}
|
|
284
|
+
if (hasComponentIssues) {
|
|
285
|
+
steps.push('3. Fix component configuration issues');
|
|
286
|
+
}
|
|
287
|
+
if (hasDependencyIssues) {
|
|
288
|
+
steps.push('4. Install missing dependencies');
|
|
289
|
+
}
|
|
290
|
+
steps.push('5. Run validation again to verify fixes');
|
|
291
|
+
steps.push('6. Test your components work correctly in development');
|
|
292
|
+
return steps;
|
|
293
|
+
}
|
|
294
|
+
generateAutoFixActions(errorAnalysis) {
|
|
295
|
+
const actions = [];
|
|
296
|
+
for (const error of errorAnalysis) {
|
|
297
|
+
switch (error.category) {
|
|
298
|
+
case 'project-config':
|
|
299
|
+
actions.push({
|
|
300
|
+
action: 'fix-project-config',
|
|
301
|
+
description: 'Generate valid hsproject.json configuration',
|
|
302
|
+
tool: 'generateProjectConfig',
|
|
303
|
+
});
|
|
304
|
+
break;
|
|
305
|
+
case 'dependencies':
|
|
306
|
+
actions.push({
|
|
307
|
+
action: 'install-dependencies',
|
|
308
|
+
description: 'Install missing npm dependencies',
|
|
309
|
+
command: 'npm install',
|
|
310
|
+
});
|
|
311
|
+
break;
|
|
312
|
+
case 'component-config':
|
|
313
|
+
actions.push({
|
|
314
|
+
action: 'fix-component-config',
|
|
315
|
+
description: `Fix ${error.component} component configuration`,
|
|
316
|
+
tool: `generate${error.component}Component`,
|
|
317
|
+
});
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return actions;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
export default ValidateProjectTool;
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.7.0-experimental.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",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@hubspot/local-dev-lib": "
|
|
8
|
+
"@hubspot/local-dev-lib": "3.7.0",
|
|
9
9
|
"@hubspot/project-parsing-lib": "0.2.0",
|
|
10
10
|
"@hubspot/serverless-dev-runtime": "7.0.2",
|
|
11
11
|
"@hubspot/theme-preview-dev-server": "0.0.10",
|
|
12
12
|
"@hubspot/ui-extensions-dev-server": "0.8.52",
|
|
13
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
13
14
|
"archiver": "7.0.1",
|
|
14
15
|
"boxen": "8.0.1",
|
|
15
16
|
"chalk": "4.1.2",
|
|
@@ -21,6 +22,7 @@
|
|
|
21
22
|
"fs-extra": "8.1.0",
|
|
22
23
|
"inquirer": "8.2.0",
|
|
23
24
|
"js-yaml": "4.1.0",
|
|
25
|
+
"mcp-framework": "^0.2.2",
|
|
24
26
|
"moment": "2.30.1",
|
|
25
27
|
"open": "7.4.2",
|
|
26
28
|
"p-queue": "6.6.2",
|
|
@@ -98,7 +100,8 @@
|
|
|
98
100
|
},
|
|
99
101
|
"bin": {
|
|
100
102
|
"hs": "./bin/hs",
|
|
101
|
-
"hscms": "./bin/hscms"
|
|
103
|
+
"hscms": "./bin/hscms",
|
|
104
|
+
"hsmcp": "./bin/hsmcp.js"
|
|
102
105
|
},
|
|
103
106
|
"publishConfig": {
|
|
104
107
|
"access": "public",
|
|
@@ -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;
|
package/commands/testAccount.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const create_1 = __importDefault(require("./testAccount/create"));
|
|
7
|
-
const yargsUtils_1 = require("../lib/yargsUtils");
|
|
8
|
-
const command = ['test-account', 'test-accounts'];
|
|
9
|
-
const describe = 'Test account';
|
|
10
|
-
function secretBuilder(yargs) {
|
|
11
|
-
yargs.command(create_1.default).demandCommand(1, '');
|
|
12
|
-
return yargs;
|
|
13
|
-
}
|
|
14
|
-
const builder = (0, yargsUtils_1.makeYargsBuilder)(secretBuilder, command, describe);
|
|
15
|
-
const testAccountCommand = {
|
|
16
|
-
command,
|
|
17
|
-
describe,
|
|
18
|
-
builder,
|
|
19
|
-
handler: () => { },
|
|
20
|
-
};
|
|
21
|
-
exports.default = testAccountCommand;
|
|
22
|
-
// TODO Remove this legacy export once we've migrated all commands to TS
|
|
23
|
-
module.exports = testAccountCommand;
|