@hubspot/cli 7.6.0-beta.12 → 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 +10 -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 +41 -13
- 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 +14 -3
- package/lang/en.js +16 -4
- package/lib/app/__tests__/migrate.test.js +14 -51
- package/lib/app/migrate.d.ts +2 -8
- package/lib/app/migrate.js +5 -80
- package/lib/constants.d.ts +6 -0
- package/lib/constants.js +6 -0
- package/lib/links.d.ts +1 -0
- package/lib/links.js +10 -3
- 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/lib/theme/__tests__/migrate.test.d.ts +1 -0
- package/lib/theme/__tests__/migrate.test.js +233 -0
- package/lib/theme/migrate.d.ts +13 -0
- package/lib/theme/migrate.js +90 -0
- package/lib/usageTracking.js +2 -2
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +2 -2
- package/mcp-server/tools/project/CreateProjectTool.d.ts +2 -2
- package/mcp-server/tools/project/DocsSearchTool.d.ts +4 -1
- package/mcp-server/tools/project/DocsSearchTool.js +5 -5
- package/mcp-server/tools/project/GetConfigValuesTool.d.ts +4 -1
- package/mcp-server/tools/project/GetConfigValuesTool.js +10 -4
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +12 -10
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +8 -7
- package/mcp-server/utils/__tests__/cliConfig.test.d.ts +1 -0
- package/mcp-server/utils/__tests__/cliConfig.test.js +110 -0
- package/mcp-server/utils/cliConfig.d.ts +1 -0
- package/mcp-server/utils/cliConfig.js +12 -0
- package/package.json +4 -4
- package/types/LocalDev.d.ts +19 -3
- package/ui/index.js +1 -1
|
@@ -2,19 +2,22 @@ import { TextContentResponse, Tool } from '../../types.js';
|
|
|
2
2
|
import { McpServer, RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
declare const inputSchemaZodObject: z.ZodObject<{
|
|
5
|
+
absoluteCurrentWorkingDirectory: z.ZodString;
|
|
5
6
|
platformVersion: z.ZodString;
|
|
6
7
|
featureType: z.ZodString;
|
|
7
8
|
}, "strip", z.ZodTypeAny, {
|
|
8
9
|
platformVersion: string;
|
|
10
|
+
absoluteCurrentWorkingDirectory: string;
|
|
9
11
|
featureType: string;
|
|
10
12
|
}, {
|
|
11
13
|
platformVersion: string;
|
|
14
|
+
absoluteCurrentWorkingDirectory: string;
|
|
12
15
|
featureType: string;
|
|
13
16
|
}>;
|
|
14
17
|
type InputSchemaType = z.infer<typeof inputSchemaZodObject>;
|
|
15
18
|
export declare class GetConfigValuesTool extends Tool<InputSchemaType> {
|
|
16
19
|
constructor(mcpServer: McpServer);
|
|
17
|
-
handler({ platformVersion, featureType, }: InputSchemaType): Promise<TextContentResponse>;
|
|
20
|
+
handler({ absoluteCurrentWorkingDirectory, platformVersion, featureType, }: InputSchemaType): Promise<TextContentResponse>;
|
|
18
21
|
register(): RegisteredTool;
|
|
19
22
|
}
|
|
20
23
|
export {};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Tool } from '../../types.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { formatTextContents } from '../../utils/content.js';
|
|
4
|
+
import { absoluteCurrentWorkingDirectory } from './constants.js';
|
|
4
5
|
import { getIntermediateRepresentationSchema, mapToInternalType, } from '@hubspot/project-parsing-lib';
|
|
5
|
-
import { getAccountId, getConfigPath, loadConfig, } from '@hubspot/local-dev-lib/config';
|
|
6
6
|
import { useV3Api } from '../../../lib/projects/platformVersion.js';
|
|
7
|
+
import { getAccountIdFromCliConfig } from '../../utils/cliConfig.js';
|
|
7
8
|
const inputSchema = {
|
|
9
|
+
absoluteCurrentWorkingDirectory,
|
|
8
10
|
platformVersion: z
|
|
9
11
|
.string()
|
|
10
12
|
.describe('The platform version for the project. Located in the hsproject.json file.'),
|
|
@@ -21,16 +23,20 @@ export class GetConfigValuesTool extends Tool {
|
|
|
21
23
|
constructor(mcpServer) {
|
|
22
24
|
super(mcpServer);
|
|
23
25
|
}
|
|
24
|
-
async handler({ platformVersion, featureType, }) {
|
|
26
|
+
async handler({ absoluteCurrentWorkingDirectory, platformVersion, featureType, }) {
|
|
25
27
|
try {
|
|
26
28
|
if (!useV3Api(platformVersion)) {
|
|
27
29
|
return formatTextContents(`Can only be used on projects with a minimum platformVersion of 2025.2`);
|
|
28
30
|
}
|
|
29
|
-
|
|
31
|
+
const accountId = getAccountIdFromCliConfig(absoluteCurrentWorkingDirectory);
|
|
32
|
+
if (!accountId) {
|
|
33
|
+
const authErrorMessage = `No account ID found. Please run \`hs account auth\` to configure an account, or set a default account with \`hs account use <account>\``;
|
|
34
|
+
return formatTextContents(authErrorMessage);
|
|
35
|
+
}
|
|
30
36
|
const schema = await getIntermediateRepresentationSchema({
|
|
31
37
|
platformVersion,
|
|
32
38
|
projectSourceDir: '',
|
|
33
|
-
accountId
|
|
39
|
+
accountId,
|
|
34
40
|
});
|
|
35
41
|
const internalComponentType = mapToInternalType(featureType);
|
|
36
42
|
if (schema[internalComponentType]) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { DocsSearchTool } from '../DocsSearchTool.js';
|
|
2
2
|
import { http } from '@hubspot/local-dev-lib/http';
|
|
3
|
-
import { getAccountId } from '@hubspot/local-dev-lib/config';
|
|
4
3
|
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
4
|
+
import { getAccountIdFromCliConfig } from '../../../utils/cliConfig.js';
|
|
5
5
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
6
6
|
vi.mock('@hubspot/local-dev-lib/http');
|
|
7
|
-
vi.mock('@hubspot/local-dev-lib/config');
|
|
8
7
|
vi.mock('@hubspot/local-dev-lib/errors/index');
|
|
9
8
|
vi.mock('../../../utils/toolUsageTracking');
|
|
9
|
+
vi.mock('../../../utils/cliConfig.js');
|
|
10
10
|
const mockHttp = http;
|
|
11
|
-
const
|
|
11
|
+
const mockGetAccountIdFromCliConfig = getAccountIdFromCliConfig;
|
|
12
12
|
const mockIsHubSpotHttpError = vi.mocked(isHubSpotHttpError);
|
|
13
13
|
describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
14
14
|
let mockMcpServer;
|
|
@@ -38,9 +38,10 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
38
38
|
describe('handler', () => {
|
|
39
39
|
const mockInput = {
|
|
40
40
|
docsSearchQuery: 'test query',
|
|
41
|
+
absoluteCurrentWorkingDirectory: '/foo',
|
|
41
42
|
};
|
|
42
43
|
it('should return auth error message when no account ID is found', async () => {
|
|
43
|
-
|
|
44
|
+
mockGetAccountIdFromCliConfig.mockReturnValue(null);
|
|
44
45
|
const result = await tool.handler(mockInput);
|
|
45
46
|
expect(result).toEqual({
|
|
46
47
|
content: [
|
|
@@ -52,7 +53,7 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
52
53
|
});
|
|
53
54
|
});
|
|
54
55
|
it('should return successful results when docs are found', async () => {
|
|
55
|
-
|
|
56
|
+
mockGetAccountIdFromCliConfig.mockReturnValue(12345);
|
|
56
57
|
const mockResponse = {
|
|
57
58
|
results: [
|
|
58
59
|
{
|
|
@@ -76,6 +77,7 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
76
77
|
data: mockResponse,
|
|
77
78
|
});
|
|
78
79
|
const result = await tool.handler(mockInput);
|
|
80
|
+
expect(mockGetAccountIdFromCliConfig).toHaveBeenCalledWith('/foo');
|
|
79
81
|
expect(mockHttp.post).toHaveBeenCalledWith(12345, {
|
|
80
82
|
url: 'dev/docs/llms/v1/docs-search',
|
|
81
83
|
data: {
|
|
@@ -103,7 +105,7 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
103
105
|
expect(resultText).toContain('Test content 2');
|
|
104
106
|
});
|
|
105
107
|
it('should return no results message when no documentation is found', async () => {
|
|
106
|
-
|
|
108
|
+
mockGetAccountIdFromCliConfig.mockReturnValue(12345);
|
|
107
109
|
const mockResponse = {
|
|
108
110
|
results: [],
|
|
109
111
|
};
|
|
@@ -122,7 +124,7 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
122
124
|
});
|
|
123
125
|
});
|
|
124
126
|
it('should return no results message when results is null', async () => {
|
|
125
|
-
|
|
127
|
+
mockGetAccountIdFromCliConfig.mockReturnValue(12345);
|
|
126
128
|
const mockResponse = {
|
|
127
129
|
results: null,
|
|
128
130
|
};
|
|
@@ -141,7 +143,7 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
141
143
|
});
|
|
142
144
|
});
|
|
143
145
|
it('should handle HubSpot HTTP errors', async () => {
|
|
144
|
-
|
|
146
|
+
mockGetAccountIdFromCliConfig.mockReturnValue(12345);
|
|
145
147
|
const mockError = {
|
|
146
148
|
toString: () => 'HubSpot API Error: 404 Not Found',
|
|
147
149
|
};
|
|
@@ -158,7 +160,7 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
158
160
|
});
|
|
159
161
|
});
|
|
160
162
|
it('should handle generic errors', async () => {
|
|
161
|
-
|
|
163
|
+
mockGetAccountIdFromCliConfig.mockReturnValue(12345);
|
|
162
164
|
const mockError = new Error('Network error');
|
|
163
165
|
mockHttp.post.mockRejectedValue(mockError);
|
|
164
166
|
mockIsHubSpotHttpError.mockReturnValue(false);
|
|
@@ -173,7 +175,7 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
173
175
|
});
|
|
174
176
|
});
|
|
175
177
|
it('should handle non-Error rejections', async () => {
|
|
176
|
-
|
|
178
|
+
mockGetAccountIdFromCliConfig.mockReturnValue(12345);
|
|
177
179
|
mockHttp.post.mockRejectedValue('String error');
|
|
178
180
|
mockIsHubSpotHttpError.mockReturnValue(false);
|
|
179
181
|
const result = await tool.handler(mockInput);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { GetConfigValuesTool } from '../GetConfigValuesTool.js';
|
|
2
2
|
import { getIntermediateRepresentationSchema, mapToInternalType, } from '@hubspot/project-parsing-lib';
|
|
3
|
-
import {
|
|
3
|
+
import { getAccountIdFromCliConfig } from '../../../utils/cliConfig.js';
|
|
4
4
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
5
5
|
vi.mock('@hubspot/project-parsing-lib');
|
|
6
|
-
vi.mock('
|
|
6
|
+
vi.mock('../../../utils/cliConfig.js');
|
|
7
7
|
vi.mock('../../../utils/toolUsageTracking');
|
|
8
8
|
const mockGetIntermediateRepresentationSchema = getIntermediateRepresentationSchema;
|
|
9
9
|
const mockMapToInternalType = mapToInternalType;
|
|
10
|
-
const
|
|
10
|
+
const mockGetAccountIdFromCliConfig = getAccountIdFromCliConfig;
|
|
11
11
|
describe('mcp-server/tools/project/GetConfigValuesTool', () => {
|
|
12
12
|
let mockMcpServer;
|
|
13
13
|
let tool;
|
|
@@ -44,9 +44,10 @@ describe('mcp-server/tools/project/GetConfigValuesTool', () => {
|
|
|
44
44
|
const input = {
|
|
45
45
|
platformVersion: '2025.2',
|
|
46
46
|
featureType: 'card',
|
|
47
|
+
absoluteCurrentWorkingDirectory: '/foo',
|
|
47
48
|
};
|
|
48
49
|
beforeEach(() => {
|
|
49
|
-
|
|
50
|
+
mockGetAccountIdFromCliConfig.mockReturnValue(123456789);
|
|
50
51
|
});
|
|
51
52
|
it('should return config schema when component type exists', async () => {
|
|
52
53
|
const mockSchema = {
|
|
@@ -61,6 +62,7 @@ describe('mcp-server/tools/project/GetConfigValuesTool', () => {
|
|
|
61
62
|
mockGetIntermediateRepresentationSchema.mockResolvedValue(mockSchema);
|
|
62
63
|
mockMapToInternalType.mockReturnValue('internal-card-type');
|
|
63
64
|
const result = await tool.handler(input);
|
|
65
|
+
expect(mockGetAccountIdFromCliConfig).toHaveBeenCalledWith('/foo');
|
|
64
66
|
expect(mockGetIntermediateRepresentationSchema).toHaveBeenCalledWith({
|
|
65
67
|
platformVersion: '2025.2',
|
|
66
68
|
projectSourceDir: '',
|
|
@@ -133,14 +135,13 @@ describe('mcp-server/tools/project/GetConfigValuesTool', () => {
|
|
|
133
135
|
});
|
|
134
136
|
});
|
|
135
137
|
it('should handle null account id', async () => {
|
|
136
|
-
|
|
137
|
-
mockGetIntermediateRepresentationSchema.mockRejectedValue(new Error('No account ID'));
|
|
138
|
+
mockGetAccountIdFromCliConfig.mockReturnValue(null);
|
|
138
139
|
const result = await tool.handler(input);
|
|
139
140
|
expect(result).toEqual({
|
|
140
141
|
content: [
|
|
141
142
|
{
|
|
142
143
|
type: 'text',
|
|
143
|
-
text: '
|
|
144
|
+
text: 'No account ID found. Please run `hs account auth` to configure an account, or set a default account with `hs account use <account>`',
|
|
144
145
|
},
|
|
145
146
|
],
|
|
146
147
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { getAccountIdFromCliConfig } from '../cliConfig.js';
|
|
2
|
+
import { configFileExists, findConfig, getAccountId, loadConfig, } from '@hubspot/local-dev-lib/config';
|
|
3
|
+
vi.mock('@hubspot/local-dev-lib/config');
|
|
4
|
+
const mockConfigFileExists = configFileExists;
|
|
5
|
+
const mockFindConfig = findConfig;
|
|
6
|
+
const mockGetAccountId = getAccountId;
|
|
7
|
+
const mockLoadConfig = loadConfig;
|
|
8
|
+
describe('mcp-server/utils/cliConfig', () => {
|
|
9
|
+
const mockWorkingDirectory = '/test/working/directory';
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
vi.clearAllMocks();
|
|
12
|
+
});
|
|
13
|
+
describe('getAccountIdFromCliConfig', () => {
|
|
14
|
+
it('should load global config when it exists and return account ID', () => {
|
|
15
|
+
const expectedAccountId = 12345;
|
|
16
|
+
mockConfigFileExists.mockReturnValue(true);
|
|
17
|
+
mockGetAccountId.mockReturnValue(expectedAccountId);
|
|
18
|
+
const result = getAccountIdFromCliConfig(mockWorkingDirectory);
|
|
19
|
+
expect(mockConfigFileExists).toHaveBeenCalledWith(true);
|
|
20
|
+
expect(mockLoadConfig).toHaveBeenCalledWith('');
|
|
21
|
+
expect(mockFindConfig).not.toHaveBeenCalled();
|
|
22
|
+
expect(mockGetAccountId).toHaveBeenCalledWith(undefined);
|
|
23
|
+
expect(result).toBe(expectedAccountId);
|
|
24
|
+
});
|
|
25
|
+
it('should load local config when global config does not exist and return account ID', () => {
|
|
26
|
+
const expectedAccountId = 67890;
|
|
27
|
+
const localConfigPath = '/path/to/local/config';
|
|
28
|
+
mockConfigFileExists.mockReturnValue(false);
|
|
29
|
+
mockFindConfig.mockReturnValue(localConfigPath);
|
|
30
|
+
mockGetAccountId.mockReturnValue(expectedAccountId);
|
|
31
|
+
const result = getAccountIdFromCliConfig(mockWorkingDirectory);
|
|
32
|
+
expect(mockConfigFileExists).toHaveBeenCalledWith(true);
|
|
33
|
+
expect(mockFindConfig).toHaveBeenCalledWith(mockWorkingDirectory);
|
|
34
|
+
expect(mockLoadConfig).toHaveBeenCalledWith(localConfigPath);
|
|
35
|
+
expect(mockGetAccountId).toHaveBeenCalledWith(undefined);
|
|
36
|
+
expect(result).toBe(expectedAccountId);
|
|
37
|
+
});
|
|
38
|
+
it('should pass accountNameOrId parameter to getAccountId when provided as string', () => {
|
|
39
|
+
const expectedAccountId = 11111;
|
|
40
|
+
const accountName = 'test-account';
|
|
41
|
+
mockConfigFileExists.mockReturnValue(true);
|
|
42
|
+
mockGetAccountId.mockReturnValue(expectedAccountId);
|
|
43
|
+
const result = getAccountIdFromCliConfig(mockWorkingDirectory, accountName);
|
|
44
|
+
expect(mockConfigFileExists).toHaveBeenCalledWith(true);
|
|
45
|
+
expect(mockLoadConfig).toHaveBeenCalledWith('');
|
|
46
|
+
expect(mockGetAccountId).toHaveBeenCalledWith(accountName);
|
|
47
|
+
expect(result).toBe(expectedAccountId);
|
|
48
|
+
});
|
|
49
|
+
it('should pass accountNameOrId parameter to getAccountId when provided as number', () => {
|
|
50
|
+
const expectedAccountId = 22222;
|
|
51
|
+
const accountId = 22222;
|
|
52
|
+
mockConfigFileExists.mockReturnValue(true);
|
|
53
|
+
mockGetAccountId.mockReturnValue(expectedAccountId);
|
|
54
|
+
const result = getAccountIdFromCliConfig(mockWorkingDirectory, accountId);
|
|
55
|
+
expect(mockConfigFileExists).toHaveBeenCalledWith(true);
|
|
56
|
+
expect(mockLoadConfig).toHaveBeenCalledWith('');
|
|
57
|
+
expect(mockGetAccountId).toHaveBeenCalledWith(accountId);
|
|
58
|
+
expect(result).toBe(expectedAccountId);
|
|
59
|
+
});
|
|
60
|
+
it('should return null when getAccountId returns null', () => {
|
|
61
|
+
mockConfigFileExists.mockReturnValue(true);
|
|
62
|
+
mockGetAccountId.mockReturnValue(null);
|
|
63
|
+
const result = getAccountIdFromCliConfig(mockWorkingDirectory);
|
|
64
|
+
expect(mockConfigFileExists).toHaveBeenCalledWith(true);
|
|
65
|
+
expect(mockLoadConfig).toHaveBeenCalledWith('');
|
|
66
|
+
expect(mockGetAccountId).toHaveBeenCalledWith(undefined);
|
|
67
|
+
expect(result).toBeNull();
|
|
68
|
+
});
|
|
69
|
+
it('should handle findConfig returning null by passing null to loadConfig', () => {
|
|
70
|
+
const expectedAccountId = 33333;
|
|
71
|
+
mockConfigFileExists.mockReturnValue(false);
|
|
72
|
+
mockFindConfig.mockReturnValue(null);
|
|
73
|
+
mockGetAccountId.mockReturnValue(expectedAccountId);
|
|
74
|
+
const result = getAccountIdFromCliConfig(mockWorkingDirectory);
|
|
75
|
+
expect(mockConfigFileExists).toHaveBeenCalledWith(true);
|
|
76
|
+
expect(mockFindConfig).toHaveBeenCalledWith(mockWorkingDirectory);
|
|
77
|
+
expect(mockLoadConfig).toHaveBeenCalledWith(null);
|
|
78
|
+
expect(mockGetAccountId).toHaveBeenCalledWith(undefined);
|
|
79
|
+
expect(result).toBe(expectedAccountId);
|
|
80
|
+
});
|
|
81
|
+
it('should work with local config when provided with account name parameter', () => {
|
|
82
|
+
const expectedAccountId = 44444;
|
|
83
|
+
const accountName = 'local-test-account';
|
|
84
|
+
const localConfigPath = '/path/to/local/config';
|
|
85
|
+
mockConfigFileExists.mockReturnValue(false);
|
|
86
|
+
mockFindConfig.mockReturnValue(localConfigPath);
|
|
87
|
+
mockGetAccountId.mockReturnValue(expectedAccountId);
|
|
88
|
+
const result = getAccountIdFromCliConfig(mockWorkingDirectory, accountName);
|
|
89
|
+
expect(mockConfigFileExists).toHaveBeenCalledWith(true);
|
|
90
|
+
expect(mockFindConfig).toHaveBeenCalledWith(mockWorkingDirectory);
|
|
91
|
+
expect(mockLoadConfig).toHaveBeenCalledWith(localConfigPath);
|
|
92
|
+
expect(mockGetAccountId).toHaveBeenCalledWith(accountName);
|
|
93
|
+
expect(result).toBe(expectedAccountId);
|
|
94
|
+
});
|
|
95
|
+
it('should work with local config when provided with account ID parameter', () => {
|
|
96
|
+
const expectedAccountId = 55555;
|
|
97
|
+
const accountId = 55555;
|
|
98
|
+
const localConfigPath = '/path/to/local/config';
|
|
99
|
+
mockConfigFileExists.mockReturnValue(false);
|
|
100
|
+
mockFindConfig.mockReturnValue(localConfigPath);
|
|
101
|
+
mockGetAccountId.mockReturnValue(expectedAccountId);
|
|
102
|
+
const result = getAccountIdFromCliConfig(mockWorkingDirectory, accountId);
|
|
103
|
+
expect(mockConfigFileExists).toHaveBeenCalledWith(true);
|
|
104
|
+
expect(mockFindConfig).toHaveBeenCalledWith(mockWorkingDirectory);
|
|
105
|
+
expect(mockLoadConfig).toHaveBeenCalledWith(localConfigPath);
|
|
106
|
+
expect(mockGetAccountId).toHaveBeenCalledWith(accountId);
|
|
107
|
+
expect(result).toBe(expectedAccountId);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getAccountIdFromCliConfig(absolutePathToWorkingDirectory: string, accountNameOrId?: string | number): number | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { configFileExists, findConfig, getAccountId, loadConfig, } from '@hubspot/local-dev-lib/config';
|
|
2
|
+
export function getAccountIdFromCliConfig(absolutePathToWorkingDirectory, accountNameOrId) {
|
|
3
|
+
const globalConfigExists = configFileExists(true);
|
|
4
|
+
if (globalConfigExists) {
|
|
5
|
+
loadConfig('');
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
const configPath = findConfig(absolutePathToWorkingDirectory);
|
|
9
|
+
loadConfig(configPath);
|
|
10
|
+
}
|
|
11
|
+
return getAccountId(accountNameOrId);
|
|
12
|
+
}
|
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();
|