@hubspot/cli 7.7.0-experimental.2 → 7.7.0-experimental.3
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/commands/project.js +0 -2
- package/commands/testAccount/create.d.ts +7 -0
- package/commands/testAccount/create.js +118 -0
- package/commands/testAccount/delete.d.ts +6 -0
- package/commands/testAccount/delete.js +42 -0
- package/commands/testAccount.d.ts +3 -0
- package/commands/testAccount.js +27 -0
- package/lang/en.d.ts +0 -51
- package/lang/en.js +0 -51
- package/lib/prompts/promptUtils.d.ts +1 -0
- package/lib/prompts/promptUtils.js +2 -0
- package/package.json +3 -6
- package/bin/hsmcp.d.ts +0 -2
- package/bin/hsmcp.js +0 -13
- package/commands/project/validate.d.ts +0 -4
- package/commands/project/validate.js +0 -53
- package/commands/setupMcp.d.ts +0 -8
- package/commands/setupMcp.js +0 -229
- package/mcp-server/index.d.ts +0 -1
- package/mcp-server/index.js +0 -17
- package/mcp-server/mcpLoader.d.ts +0 -5
- package/mcp-server/mcpLoader.js +0 -24
- package/mcp-server/tools/ExplainProjectStructureTool.d.ts +0 -33
- package/mcp-server/tools/ExplainProjectStructureTool.js +0 -266
- package/mcp-server/tools/GenerateAppComponentTool.d.ts +0 -99
- package/mcp-server/tools/GenerateAppComponentTool.js +0 -193
- package/mcp-server/tools/GenerateCardComponentTool.d.ts +0 -74
- package/mcp-server/tools/GenerateCardComponentTool.js +0 -146
- package/mcp-server/tools/GenerateProjectConfigTool.d.ts +0 -32
- package/mcp-server/tools/GenerateProjectConfigTool.js +0 -40
- package/mcp-server/tools/HubSpotCLIHelper.d.ts +0 -24
- package/mcp-server/tools/HubSpotCLIHelper.js +0 -110
- package/mcp-server/tools/UploadProjectTool.d.ts +0 -44
- package/mcp-server/tools/UploadProjectTool.js +0 -166
- package/mcp-server/tools/ValidateProjectTool.d.ts +0 -62
- package/mcp-server/tools/ValidateProjectTool.js +0 -336
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { MCPTool } from 'mcp-framework';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import HubSpotCLIHelper from './HubSpotCLIHelper.js';
|
|
4
|
-
class UploadProjectTool extends MCPTool {
|
|
5
|
-
name = 'uploadProject';
|
|
6
|
-
description = 'Uploads a developer project to HubSpot using the HubSpot CLI';
|
|
7
|
-
cliHelper = new HubSpotCLIHelper();
|
|
8
|
-
schema = {
|
|
9
|
-
projectPath: {
|
|
10
|
-
type: z.string().optional(),
|
|
11
|
-
description: 'Path to the project directory. When using MCP server globally, provide the absolute path to your project (e.g., "/Users/yourname/projects/my-hubspot-project"). Defaults to "." for local usage.',
|
|
12
|
-
},
|
|
13
|
-
accountId: {
|
|
14
|
-
type: z.string().optional(),
|
|
15
|
-
description: 'HubSpot account ID to upload to. If not provided, uses CLI default or prompts',
|
|
16
|
-
},
|
|
17
|
-
autoInstallCLI: {
|
|
18
|
-
type: z.boolean().optional(),
|
|
19
|
-
description: 'Whether to automatically install HubSpot CLI if not found. Defaults to false',
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
async execute(input) {
|
|
23
|
-
// Default to current directory "." which should resolve relative to where the MCP client is running
|
|
24
|
-
const { projectPath = '.', accountId, autoInstallCLI = false } = input;
|
|
25
|
-
try {
|
|
26
|
-
// Step 1: Check if HubSpot CLI is installed
|
|
27
|
-
const cliCheckResult = await this.cliHelper.checkCLIInstallation();
|
|
28
|
-
if (!cliCheckResult.isInstalled) {
|
|
29
|
-
if (autoInstallCLI) {
|
|
30
|
-
// Attempt to install CLI automatically
|
|
31
|
-
const installResult = await this.cliHelper.installCLI();
|
|
32
|
-
if (!installResult.success) {
|
|
33
|
-
return {
|
|
34
|
-
status: 'cli-install-failed',
|
|
35
|
-
message: '❌ Failed to install HubSpot CLI automatically',
|
|
36
|
-
error: installResult.error,
|
|
37
|
-
actions: [
|
|
38
|
-
{
|
|
39
|
-
action: 'install-cli-manually',
|
|
40
|
-
command: 'npm install -g @hubspot/cli',
|
|
41
|
-
description: 'Install HubSpot CLI manually',
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
troubleshooting: [
|
|
45
|
-
'Try installing the CLI manually: npm install -g @hubspot/cli',
|
|
46
|
-
'Ensure you have npm installed and proper permissions',
|
|
47
|
-
'Run the upload command again after CLI installation',
|
|
48
|
-
],
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
// Verify installation was successful
|
|
52
|
-
const recheckResult = await this.cliHelper.checkCLIInstallation();
|
|
53
|
-
if (!recheckResult.isInstalled) {
|
|
54
|
-
return {
|
|
55
|
-
status: 'cli-install-verification-failed',
|
|
56
|
-
message: '❌ CLI installation completed but verification failed',
|
|
57
|
-
troubleshooting: [
|
|
58
|
-
"Try running 'hs --version' manually to verify installation",
|
|
59
|
-
'Restart your terminal/shell session',
|
|
60
|
-
'Check if the CLI was installed to the correct PATH',
|
|
61
|
-
],
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
return {
|
|
67
|
-
status: 'cli-not-found',
|
|
68
|
-
message: 'HubSpot CLI not found. Install it to upload projects.',
|
|
69
|
-
error: `Debug info: ${JSON.stringify(cliCheckResult.debugInfo, null, 2)}`,
|
|
70
|
-
actions: [
|
|
71
|
-
{
|
|
72
|
-
action: 'install-cli',
|
|
73
|
-
command: 'npm install -g @hubspot/cli',
|
|
74
|
-
description: 'Install HubSpot CLI globally',
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
nextSteps: [
|
|
78
|
-
'1. Install HubSpot CLI globally',
|
|
79
|
-
'2. Authenticate with your HubSpot account (hs auth)',
|
|
80
|
-
'3. Run project upload again',
|
|
81
|
-
],
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
// Step 2: Build the upload command
|
|
86
|
-
let uploadCommand = 'hs project upload';
|
|
87
|
-
if (accountId) {
|
|
88
|
-
uploadCommand += ` --account=${accountId}`;
|
|
89
|
-
}
|
|
90
|
-
// Step 3: Run project upload
|
|
91
|
-
const uploadResult = await this.cliHelper.runProjectCommand(uploadCommand, projectPath);
|
|
92
|
-
if (uploadResult.success) {
|
|
93
|
-
// Parse successful upload output
|
|
94
|
-
const output = uploadResult.output;
|
|
95
|
-
return {
|
|
96
|
-
status: 'success',
|
|
97
|
-
message: '✅ Project uploaded successfully to HubSpot!',
|
|
98
|
-
cliVersion: cliCheckResult.version,
|
|
99
|
-
uploadOutput: output,
|
|
100
|
-
accountId: accountId,
|
|
101
|
-
projectPath: projectPath,
|
|
102
|
-
nextSteps: [
|
|
103
|
-
'1. Check your HubSpot account to verify the project appears',
|
|
104
|
-
'2. Test your components in the HubSpot environment',
|
|
105
|
-
'3. Monitor for any runtime errors or issues',
|
|
106
|
-
"4. Use 'hs project logs' to view application logs if needed",
|
|
107
|
-
],
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
// Parse upload failure
|
|
112
|
-
const errorOutput = uploadResult.output || uploadResult.error || 'Upload failed';
|
|
113
|
-
// Check if this looks like a path issue with global MCP server
|
|
114
|
-
const isPathIssue = errorOutput.includes('Unable to locate a project configuration file') || errorOutput.includes('MCP Server CWD: /');
|
|
115
|
-
return {
|
|
116
|
-
status: 'upload-failed',
|
|
117
|
-
message: '❌ Project upload failed',
|
|
118
|
-
cliVersion: cliCheckResult.version,
|
|
119
|
-
uploadOutput: errorOutput,
|
|
120
|
-
error: uploadResult.error,
|
|
121
|
-
troubleshooting: [
|
|
122
|
-
"Ensure you're authenticated: run 'hs auth' to login",
|
|
123
|
-
'Verify your account has permission to upload projects',
|
|
124
|
-
"Check that your project is valid: run 'hs project validate' first",
|
|
125
|
-
'Ensure you have network connectivity to HubSpot',
|
|
126
|
-
'Try uploading to a different account if you have access to multiple',
|
|
127
|
-
`Working directory was: ${projectPath}`,
|
|
128
|
-
...(isPathIssue
|
|
129
|
-
? [
|
|
130
|
-
'⚠️ PATH ISSUE DETECTED: You may be using the global MCP server',
|
|
131
|
-
'When using global MCP server, provide the absolute path to your project:',
|
|
132
|
-
'Example: {"projectPath": "/Users/yourname/projects/my-hubspot-project"}',
|
|
133
|
-
'Or consider running the MCP server locally from your project directory',
|
|
134
|
-
]
|
|
135
|
-
: []),
|
|
136
|
-
],
|
|
137
|
-
nextSteps: [
|
|
138
|
-
'1. Check authentication status: hs auth info',
|
|
139
|
-
'2. Validate project first: hs project validate',
|
|
140
|
-
...(isPathIssue
|
|
141
|
-
? ['3. Provide absolute projectPath if using global MCP server']
|
|
142
|
-
: []),
|
|
143
|
-
'4. Review the error output above for specific issues',
|
|
144
|
-
'5. Try the upload command again after fixing issues',
|
|
145
|
-
],
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
151
|
-
return {
|
|
152
|
-
status: 'error',
|
|
153
|
-
message: 'An error occurred during project upload',
|
|
154
|
-
error: errorMessage,
|
|
155
|
-
troubleshooting: [
|
|
156
|
-
"Ensure you're in a valid developer project directory",
|
|
157
|
-
'Check that hsproject.json exists in the project root',
|
|
158
|
-
'Verify HubSpot CLI is properly installed and accessible',
|
|
159
|
-
"Try running 'hs project upload' manually to see detailed output",
|
|
160
|
-
`Attempted project path: ${projectPath}`,
|
|
161
|
-
],
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
export default UploadProjectTool;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { MCPTool } from 'mcp-framework';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
interface ValidateProjectInput {
|
|
4
|
-
autoFix?: boolean;
|
|
5
|
-
projectPath?: string;
|
|
6
|
-
}
|
|
7
|
-
interface ValidationResponse {
|
|
8
|
-
status: string;
|
|
9
|
-
message: string;
|
|
10
|
-
cliVersion?: string;
|
|
11
|
-
validationOutput?: string;
|
|
12
|
-
errors?: string[];
|
|
13
|
-
errorAnalysis?: Array<{
|
|
14
|
-
category: string;
|
|
15
|
-
issue: string;
|
|
16
|
-
severity: 'error' | 'warning';
|
|
17
|
-
component?: string;
|
|
18
|
-
file?: string;
|
|
19
|
-
}>;
|
|
20
|
-
suggestions?: string[];
|
|
21
|
-
nextSteps?: string[];
|
|
22
|
-
autoFixActions?: Array<{
|
|
23
|
-
action: string;
|
|
24
|
-
description: string;
|
|
25
|
-
command?: string;
|
|
26
|
-
tool?: string;
|
|
27
|
-
}>;
|
|
28
|
-
actions?: Array<{
|
|
29
|
-
action: string;
|
|
30
|
-
command: string;
|
|
31
|
-
description: string;
|
|
32
|
-
}>;
|
|
33
|
-
projectStructure?: string;
|
|
34
|
-
error?: string;
|
|
35
|
-
troubleshooting?: string[];
|
|
36
|
-
}
|
|
37
|
-
declare class ValidateProjectTool extends MCPTool<ValidateProjectInput> {
|
|
38
|
-
name: string;
|
|
39
|
-
description: string;
|
|
40
|
-
private cliHelper;
|
|
41
|
-
schema: {
|
|
42
|
-
autoFix: {
|
|
43
|
-
type: z.ZodOptional<z.ZodBoolean>;
|
|
44
|
-
description: string;
|
|
45
|
-
};
|
|
46
|
-
projectPath: {
|
|
47
|
-
type: z.ZodOptional<z.ZodString>;
|
|
48
|
-
description: string;
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
execute(input: ValidateProjectInput): Promise<ValidationResponse>;
|
|
52
|
-
private runProjectValidation;
|
|
53
|
-
private runCommand;
|
|
54
|
-
private parseValidationErrors;
|
|
55
|
-
private analyzeValidationErrors;
|
|
56
|
-
private extractComponentFromPath;
|
|
57
|
-
private generateFixSuggestions;
|
|
58
|
-
private extractFieldFromError;
|
|
59
|
-
private generateNextSteps;
|
|
60
|
-
private generateAutoFixActions;
|
|
61
|
-
}
|
|
62
|
-
export default ValidateProjectTool;
|
|
@@ -1,336 +0,0 @@
|
|
|
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. When using MCP server globally, provide the absolute path to your project (e.g., "/Users/yourname/projects/my-hubspot-project"). Defaults to "." for local usage.',
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
async execute(input) {
|
|
19
|
-
// Default to current directory "." which should resolve relative to where the MCP client is running
|
|
20
|
-
const { autoFix = false, projectPath = '.' } = 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
|
-
// Add debugging information about directory context
|
|
105
|
-
if (result.output.includes('Unable to locate a project configuration file')) {
|
|
106
|
-
errors.push(`Working directory was: ${projectPath}`);
|
|
107
|
-
errors.push("Make sure you're running this from a directory containing hsproject.json");
|
|
108
|
-
// Check if this looks like a global MCP server path issue
|
|
109
|
-
if (result.output.includes('MCP Server CWD: /')) {
|
|
110
|
-
errors.push('⚠️ PATH ISSUE DETECTED: You may be using the global MCP server');
|
|
111
|
-
errors.push('When using global MCP server, provide the absolute path to your project:');
|
|
112
|
-
errors.push('Example: {"projectPath": "/Users/yourname/projects/my-hubspot-project"}');
|
|
113
|
-
errors.push('Or consider running the MCP server locally from your project directory');
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
isValid: isValid,
|
|
118
|
-
output: output,
|
|
119
|
-
errors: errors,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
// Command failed to run
|
|
124
|
-
const errorMessage = result.error || 'Failed to run project validation';
|
|
125
|
-
const errors = [errorMessage];
|
|
126
|
-
// Add debugging information about directory context
|
|
127
|
-
if (result.output.includes('Unable to locate a project configuration file')) {
|
|
128
|
-
errors.push(`Working directory was: ${projectPath}`);
|
|
129
|
-
errors.push("Make sure you're running this from a directory containing hsproject.json");
|
|
130
|
-
}
|
|
131
|
-
return {
|
|
132
|
-
isValid: false,
|
|
133
|
-
output: result.output || '',
|
|
134
|
-
errors: errors,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
catch (error) {
|
|
139
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown validation error';
|
|
140
|
-
throw new Error(`Failed to run project validation: ${errorMessage}`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
runCommand(command) {
|
|
144
|
-
// Delegate to the CLI helper
|
|
145
|
-
return this.cliHelper.runCommand(command);
|
|
146
|
-
}
|
|
147
|
-
parseValidationErrors(output) {
|
|
148
|
-
const errors = [];
|
|
149
|
-
const lines = output.split('\n');
|
|
150
|
-
let currentFile = '';
|
|
151
|
-
let inErrorSection = false;
|
|
152
|
-
for (const line of lines) {
|
|
153
|
-
// Look for file error headers like "Encountered the following errors for src/app/file.json:"
|
|
154
|
-
const fileMatch = line.match(/Encountered the following errors for (.+?):/);
|
|
155
|
-
if (fileMatch) {
|
|
156
|
-
currentFile = fileMatch[1];
|
|
157
|
-
inErrorSection = true;
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
// Parse individual error lines (start with tab and dash)
|
|
161
|
-
if (inErrorSection && line.match(/^\s*-\s+/)) {
|
|
162
|
-
const errorText = line.replace(/^\s*-\s+/, '').trim();
|
|
163
|
-
if (errorText) {
|
|
164
|
-
errors.push(`${currentFile}: ${errorText}`);
|
|
165
|
-
}
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
// Handle multi-line errors with additional indentation
|
|
169
|
-
if (inErrorSection && line.match(/^\s{2,}-\s+/)) {
|
|
170
|
-
const errorText = line.replace(/^\s*-\s+/, '').trim();
|
|
171
|
-
if (errorText && errors.length > 0) {
|
|
172
|
-
// Append to the last error as additional context
|
|
173
|
-
errors[errors.length - 1] += `\n ${errorText}`;
|
|
174
|
-
}
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
// Reset when we hit an empty line or new section
|
|
178
|
-
if (line.trim() === '' ||
|
|
179
|
-
(!line.startsWith('\t') && !line.startsWith(' '))) {
|
|
180
|
-
inErrorSection = false;
|
|
181
|
-
currentFile = '';
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return errors;
|
|
185
|
-
}
|
|
186
|
-
analyzeValidationErrors(errors) {
|
|
187
|
-
const analysis = [];
|
|
188
|
-
for (const error of errors) {
|
|
189
|
-
const filePath = error.split(':')[0];
|
|
190
|
-
const errorMessage = error.substring(error.indexOf(':') + 1).trim();
|
|
191
|
-
let category = 'unknown';
|
|
192
|
-
let component = 'unknown';
|
|
193
|
-
let severity = 'error';
|
|
194
|
-
// Extract file information
|
|
195
|
-
if (filePath.includes('hsproject.json')) {
|
|
196
|
-
category = 'project-config';
|
|
197
|
-
component = 'project';
|
|
198
|
-
}
|
|
199
|
-
else if (filePath.includes('-hsmeta.json')) {
|
|
200
|
-
category = 'component-config';
|
|
201
|
-
component = this.extractComponentFromPath(filePath);
|
|
202
|
-
}
|
|
203
|
-
else if (filePath.includes('package.json')) {
|
|
204
|
-
category = 'dependencies';
|
|
205
|
-
component = this.extractComponentFromPath(filePath);
|
|
206
|
-
severity = 'warning';
|
|
207
|
-
}
|
|
208
|
-
// Analyze error message content
|
|
209
|
-
if (errorMessage.includes('Invalid JSON')) {
|
|
210
|
-
category = 'json-syntax';
|
|
211
|
-
}
|
|
212
|
-
else if (errorMessage.includes('Missing required field')) {
|
|
213
|
-
category = 'required-field';
|
|
214
|
-
}
|
|
215
|
-
else if (errorMessage.includes('must NOT have additional properties')) {
|
|
216
|
-
category = 'schema-validation';
|
|
217
|
-
}
|
|
218
|
-
else if (errorMessage.includes('entrypoint')) {
|
|
219
|
-
category = 'entrypoint';
|
|
220
|
-
}
|
|
221
|
-
analysis.push({
|
|
222
|
-
category: category,
|
|
223
|
-
issue: errorMessage,
|
|
224
|
-
severity: severity,
|
|
225
|
-
component: component,
|
|
226
|
-
file: filePath,
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
return analysis;
|
|
230
|
-
}
|
|
231
|
-
extractComponentFromPath(filePath) {
|
|
232
|
-
// Extract component type from file path like "src/app/cards/my-card-hsmeta.json"
|
|
233
|
-
if (filePath.includes('/app/')) {
|
|
234
|
-
const pathParts = filePath.split('/app/')[1].split('/');
|
|
235
|
-
if (pathParts.length > 1) {
|
|
236
|
-
return pathParts[0]; // e.g., "cards", "functions", etc.
|
|
237
|
-
}
|
|
238
|
-
return 'app';
|
|
239
|
-
}
|
|
240
|
-
// Handle top-level app component files
|
|
241
|
-
if (filePath.includes('-hsmeta.json')) {
|
|
242
|
-
return 'app';
|
|
243
|
-
}
|
|
244
|
-
return 'unknown';
|
|
245
|
-
}
|
|
246
|
-
generateFixSuggestions(errorAnalysis) {
|
|
247
|
-
const suggestions = [];
|
|
248
|
-
for (const error of errorAnalysis) {
|
|
249
|
-
switch (error.category) {
|
|
250
|
-
case 'project-config':
|
|
251
|
-
suggestions.push("Fix hsproject.json: Ensure it contains 'name', 'srcDir', and 'platformVersion' fields", 'Use the generateProjectConfig tool to create a valid hsproject.json file');
|
|
252
|
-
break;
|
|
253
|
-
case 'component-config':
|
|
254
|
-
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`);
|
|
255
|
-
break;
|
|
256
|
-
case 'json-syntax':
|
|
257
|
-
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');
|
|
258
|
-
break;
|
|
259
|
-
case 'required-field':
|
|
260
|
-
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');
|
|
261
|
-
break;
|
|
262
|
-
case 'schema-validation':
|
|
263
|
-
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');
|
|
264
|
-
break;
|
|
265
|
-
case 'dependencies':
|
|
266
|
-
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');
|
|
267
|
-
break;
|
|
268
|
-
case 'entrypoint':
|
|
269
|
-
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');
|
|
270
|
-
break;
|
|
271
|
-
default:
|
|
272
|
-
suggestions.push(`Review error in ${error.file || 'project'}: ${error.issue}`);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
return [...new Set(suggestions)]; // Remove duplicates
|
|
276
|
-
}
|
|
277
|
-
extractFieldFromError(errorMessage) {
|
|
278
|
-
// Extract field name from messages like "Missing required field: config.description"
|
|
279
|
-
const match = errorMessage.match(/Missing required field:\s*(.+)/);
|
|
280
|
-
return match ? match[1] : 'unknown field';
|
|
281
|
-
}
|
|
282
|
-
generateNextSteps(errorAnalysis, autoFix) {
|
|
283
|
-
const steps = [];
|
|
284
|
-
if (autoFix) {
|
|
285
|
-
steps.push('1. Review auto-fix actions and apply them');
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
steps.push('1. Review the validation errors and suggestions above');
|
|
289
|
-
}
|
|
290
|
-
const hasProjectConfig = errorAnalysis.some(e => e.category === 'project-config');
|
|
291
|
-
const hasComponentIssues = errorAnalysis.some(e => e.category === 'component-config');
|
|
292
|
-
const hasDependencyIssues = errorAnalysis.some(e => e.category === 'dependencies');
|
|
293
|
-
if (hasProjectConfig) {
|
|
294
|
-
steps.push('2. Fix hsproject.json configuration issues first');
|
|
295
|
-
}
|
|
296
|
-
if (hasComponentIssues) {
|
|
297
|
-
steps.push('3. Fix component configuration issues');
|
|
298
|
-
}
|
|
299
|
-
if (hasDependencyIssues) {
|
|
300
|
-
steps.push('4. Install missing dependencies');
|
|
301
|
-
}
|
|
302
|
-
steps.push('5. Run validation again to verify fixes');
|
|
303
|
-
steps.push('6. Test your components work correctly in development');
|
|
304
|
-
return steps;
|
|
305
|
-
}
|
|
306
|
-
generateAutoFixActions(errorAnalysis) {
|
|
307
|
-
const actions = [];
|
|
308
|
-
for (const error of errorAnalysis) {
|
|
309
|
-
switch (error.category) {
|
|
310
|
-
case 'project-config':
|
|
311
|
-
actions.push({
|
|
312
|
-
action: 'fix-project-config',
|
|
313
|
-
description: 'Generate valid hsproject.json configuration',
|
|
314
|
-
tool: 'generateProjectConfig',
|
|
315
|
-
});
|
|
316
|
-
break;
|
|
317
|
-
case 'dependencies':
|
|
318
|
-
actions.push({
|
|
319
|
-
action: 'install-dependencies',
|
|
320
|
-
description: 'Install missing npm dependencies',
|
|
321
|
-
command: 'npm install',
|
|
322
|
-
});
|
|
323
|
-
break;
|
|
324
|
-
case 'component-config':
|
|
325
|
-
actions.push({
|
|
326
|
-
action: 'fix-component-config',
|
|
327
|
-
description: `Fix ${error.component} component configuration`,
|
|
328
|
-
tool: `generate${error.component}Component`,
|
|
329
|
-
});
|
|
330
|
-
break;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
return actions;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
export default ValidateProjectTool;
|