@hubspot/cli 7.6.0-beta.11 → 7.6.0-beta.13
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/app/__tests__/migrate.test.js +1 -0
- package/commands/getStarted.js +7 -20
- package/commands/mcp/setup.d.ts +0 -1
- package/commands/mcp/setup.js +11 -11
- package/commands/project/__tests__/add.test.js +64 -0
- package/commands/project/__tests__/create.test.js +57 -0
- package/commands/project/__tests__/deploy.test.js +3 -2
- package/commands/project/add.d.ts +1 -1
- package/commands/project/add.js +3 -5
- package/commands/project/create.js +7 -2
- package/commands/project/deploy.js +9 -61
- package/commands/project/dev/index.js +1 -1
- package/commands/project/dev/unifiedFlow.js +4 -1
- package/commands/project/migrate.js +26 -7
- package/commands/project/upload.js +2 -2
- package/commands/project/validate.js +1 -1
- package/commands/project/watch.js +2 -2
- package/lang/en.d.ts +20 -5
- package/lang/en.js +38 -22
- package/lang/en.lyaml +12 -12
- package/lib/__tests__/hasFeature.test.js +145 -7
- package/lib/__tests__/importData.test.js +1 -1
- package/lib/app/__tests__/migrate.test.js +14 -51
- package/lib/app/migrate.d.ts +2 -8
- package/lib/app/migrate.js +5 -73
- package/lib/constants.d.ts +4 -0
- package/lib/constants.js +4 -0
- package/lib/errorHandlers/index.d.ts +4 -0
- package/lib/errorHandlers/index.js +1 -1
- package/lib/hasFeature.js +6 -0
- package/lib/importData.js +1 -1
- package/lib/links.d.ts +1 -0
- package/lib/links.js +10 -3
- package/lib/mcp/setup.d.ts +0 -2
- package/lib/mcp/setup.js +4 -29
- package/lib/projects/__tests__/AppDevModeInterface.test.js +71 -44
- package/lib/projects/__tests__/LocalDevProcess.test.js +1 -0
- package/lib/projects/__tests__/components.test.js +164 -7
- package/lib/projects/__tests__/deploy.test.js +164 -0
- package/lib/projects/__tests__/platformVersion.test.d.ts +1 -0
- package/lib/projects/__tests__/{buildAndDeploy.test.js → platformVersion.test.js} +2 -2
- package/lib/projects/add/__tests__/legacyAddComponent.test.js +49 -6
- package/lib/projects/add/__tests__/v3AddComponent.test.js +142 -8
- package/lib/projects/add/legacyAddComponent.d.ts +1 -1
- package/lib/projects/add/legacyAddComponent.js +5 -1
- package/lib/projects/add/v3AddComponent.d.ts +2 -1
- package/lib/projects/add/v3AddComponent.js +22 -5
- package/lib/projects/components.d.ts +1 -0
- package/lib/projects/components.js +27 -1
- package/lib/projects/create/__tests__/v3.test.js +97 -9
- package/lib/projects/create/index.js +2 -2
- package/lib/projects/create/legacy.js +1 -1
- package/lib/projects/create/v3.d.ts +2 -2
- package/lib/projects/create/v3.js +35 -12
- package/lib/projects/deploy.d.ts +13 -0
- package/lib/projects/deploy.js +63 -0
- package/lib/projects/localDev/AppDevModeInterface.d.ts +5 -3
- package/lib/projects/localDev/AppDevModeInterface.js +110 -47
- package/lib/projects/localDev/DevServerManagerV2.js +1 -0
- package/lib/projects/localDev/LocalDevProcess.js +3 -1
- package/lib/projects/localDev/LocalDevState.d.ts +5 -2
- package/lib/projects/localDev/LocalDevState.js +9 -1
- package/lib/projects/localDev/helpers/project.d.ts +2 -2
- package/lib/projects/localDev/helpers/project.js +6 -8
- package/lib/projects/platformVersion.d.ts +1 -0
- package/lib/projects/platformVersion.js +10 -0
- package/lib/projects/{buildAndDeploy.d.ts → pollProjectBuildAndDeploy.d.ts} +0 -1
- package/lib/projects/{buildAndDeploy.js → pollProjectBuildAndDeploy.js} +0 -10
- package/lib/projects/upload.js +1 -1
- package/lib/projects/urls.d.ts +1 -0
- package/lib/projects/urls.js +3 -0
- package/lib/prompts/__tests__/projectAddPrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/projectAddPrompt.test.js +143 -0
- package/lib/prompts/__tests__/selectProjectTemplatePrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/selectProjectTemplatePrompt.test.js +160 -0
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +1 -0
- package/lib/prompts/importDataFilePathPrompt.js +4 -2
- package/lib/prompts/installAppPrompt.d.ts +6 -1
- package/lib/prompts/installAppPrompt.js +6 -1
- package/lib/prompts/projectAddPrompt.js +1 -1
- package/lib/prompts/promptUtils.d.ts +5 -0
- package/lib/prompts/promptUtils.js +9 -0
- package/lib/prompts/selectProjectTemplatePrompt.js +1 -1
- 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/ui/index.js +3 -6
- package/lib/usageTracking.js +2 -2
- package/mcp-server/tools/cms/HsCreateFunctionTool.d.ts +32 -0
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +96 -0
- package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +38 -0
- package/mcp-server/tools/cms/HsCreateModuleTool.js +118 -0
- package/mcp-server/tools/cms/HsCreateTemplateTool.d.ts +26 -0
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +75 -0
- package/mcp-server/tools/cms/HsFunctionLogsTool.d.ts +32 -0
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +76 -0
- package/mcp-server/tools/cms/HsListFunctionsTool.d.ts +23 -0
- package/mcp-server/tools/cms/HsListFunctionsTool.js +58 -0
- package/mcp-server/tools/cms/HsListTool.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +251 -0
- package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.js +224 -0
- package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.js +206 -0
- package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.js +183 -0
- package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.js +120 -0
- package/mcp-server/tools/cms/__tests__/HsListTool.test.js +1 -1
- package/mcp-server/tools/index.js +13 -1
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +3 -3
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +3 -3
- package/mcp-server/tools/project/CreateProjectTool.d.ts +3 -3
- package/mcp-server/tools/project/CreateProjectTool.js +5 -5
- package/mcp-server/tools/project/DeployProjectTool.js +1 -1
- package/mcp-server/tools/project/DocFetchTool.js +2 -2
- package/mcp-server/tools/project/DocsSearchTool.d.ts +4 -1
- package/mcp-server/tools/project/DocsSearchTool.js +7 -7
- package/mcp-server/tools/project/GetConfigValuesTool.d.ts +4 -1
- package/mcp-server/tools/project/GetConfigValuesTool.js +14 -8
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +1 -1
- package/mcp-server/tools/project/UploadProjectTools.js +2 -2
- package/mcp-server/tools/project/ValidateProjectTool.js +1 -1
- package/mcp-server/tools/project/__tests__/AddFeatureToProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/DeployProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +2 -2
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +14 -12
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +9 -8
- package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +1 -1
- package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +1 -1
- package/mcp-server/tools/project/constants.d.ts +1 -1
- package/mcp-server/tools/project/constants.js +14 -6
- 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 -3
- package/types/LocalDev.d.ts +2 -1
- package/types/Projects.d.ts +1 -0
- package/ui/components/BoxWithTitle.d.ts +8 -0
- package/ui/components/BoxWithTitle.js +9 -0
- package/ui/components/HorizontalSelectPrompt.d.ts +8 -0
- package/ui/components/HorizontalSelectPrompt.js +30 -0
- package/ui/components/StatusMessageBoxes.d.ts +12 -0
- package/ui/components/StatusMessageBoxes.js +31 -0
- package/ui/lib/ui-testing-utils.d.ts +9 -0
- package/ui/lib/ui-testing-utils.js +47 -0
- package/ui/lib/useTerminalSize.d.ts +13 -0
- package/ui/lib/useTerminalSize.js +31 -0
- package/ui/styles.d.ts +18 -0
- package/ui/styles.js +18 -0
- package/ui/views/UiSandbox.d.ts +5 -0
- package/ui/views/UiSandbox.js +25 -0
- /package/lib/projects/__tests__/{buildAndDeploy.test.d.ts → deploy.test.d.ts} +0 -0
|
@@ -4,6 +4,7 @@ import { getProjectComponentListFromRepo } from '../../create/legacy.js';
|
|
|
4
4
|
import { projectAddPrompt } from '../../../prompts/projectAddPrompt.js';
|
|
5
5
|
import { logger } from '@hubspot/local-dev-lib/logger';
|
|
6
6
|
import { cloneGithubRepo } from '@hubspot/local-dev-lib/github';
|
|
7
|
+
import { trackCommandUsage } from '../../../usageTracking.js';
|
|
7
8
|
import { ComponentTypes, } from '../../../../types/Projects.js';
|
|
8
9
|
import { commands } from '../../../../lang/en.js';
|
|
9
10
|
vi.mock('../../structure');
|
|
@@ -11,21 +12,25 @@ vi.mock('../../create/legacy');
|
|
|
11
12
|
vi.mock('../../../prompts/projectAddPrompt');
|
|
12
13
|
vi.mock('@hubspot/local-dev-lib/logger');
|
|
13
14
|
vi.mock('@hubspot/local-dev-lib/github');
|
|
15
|
+
vi.mock('../../../usageTracking.js');
|
|
14
16
|
const mockedFindProjectComponents = vi.mocked(findProjectComponents);
|
|
15
17
|
const mockedGetProjectComponentListFromRepo = vi.mocked(getProjectComponentListFromRepo);
|
|
16
18
|
const mockedProjectAddPrompt = vi.mocked(projectAddPrompt);
|
|
17
19
|
const mockedLogger = vi.mocked(logger);
|
|
18
20
|
const mockedCloneGithubRepo = vi.mocked(cloneGithubRepo);
|
|
21
|
+
const mockedTrackCommandUsage = vi.mocked(trackCommandUsage);
|
|
19
22
|
describe('lib/projects/add/legacyAddComponent', () => {
|
|
20
23
|
const mockProjectConfig = {
|
|
21
24
|
name: 'test-project',
|
|
22
25
|
srcDir: 'src',
|
|
23
26
|
platformVersion: 'v1',
|
|
24
27
|
};
|
|
28
|
+
const accountId = 1234567890;
|
|
25
29
|
const mockArgs = { name: 'test-component', type: 'module' };
|
|
26
30
|
const projectDir = '/path/to/project';
|
|
27
31
|
beforeEach(() => {
|
|
28
32
|
vi.resetAllMocks();
|
|
33
|
+
mockedTrackCommandUsage.mockResolvedValue();
|
|
29
34
|
});
|
|
30
35
|
describe('legacyAddComponent()', () => {
|
|
31
36
|
it('successfully adds a component to a project without public apps', async () => {
|
|
@@ -58,7 +63,7 @@ describe('lib/projects/add/legacyAddComponent', () => {
|
|
|
58
63
|
mockedGetProjectComponentListFromRepo.mockResolvedValue(mockComponentList);
|
|
59
64
|
mockedProjectAddPrompt.mockResolvedValue(mockPromptResponse);
|
|
60
65
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
61
|
-
await legacyAddComponent(mockArgs, projectDir, mockProjectConfig);
|
|
66
|
+
await legacyAddComponent(mockArgs, projectDir, mockProjectConfig, accountId);
|
|
62
67
|
expect(mockedFindProjectComponents).toHaveBeenCalledWith(projectDir);
|
|
63
68
|
expect(mockedGetProjectComponentListFromRepo).toHaveBeenCalledWith('v1');
|
|
64
69
|
expect(mockedProjectAddPrompt).toHaveBeenCalledWith(mockComponentList, mockArgs);
|
|
@@ -67,6 +72,9 @@ describe('lib/projects/add/legacyAddComponent', () => {
|
|
|
67
72
|
branch: 'main',
|
|
68
73
|
hideLogs: true,
|
|
69
74
|
}));
|
|
75
|
+
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
76
|
+
type: 'module',
|
|
77
|
+
}, accountId);
|
|
70
78
|
expect(mockedLogger.log).toHaveBeenCalledWith(commands.project.add.creatingComponent('test-project'));
|
|
71
79
|
expect(mockedLogger.success).toHaveBeenCalledWith(commands.project.add.success('new-component'));
|
|
72
80
|
});
|
|
@@ -97,7 +105,7 @@ describe('lib/projects/add/legacyAddComponent', () => {
|
|
|
97
105
|
},
|
|
98
106
|
];
|
|
99
107
|
mockedFindProjectComponents.mockResolvedValue(mockComponents);
|
|
100
|
-
await expect(legacyAddComponent(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(commands.project.add.error.projectContainsPublicApp);
|
|
108
|
+
await expect(legacyAddComponent(mockArgs, projectDir, mockProjectConfig, accountId)).rejects.toThrow(commands.project.add.error.projectContainsPublicApp);
|
|
101
109
|
expect(mockedGetProjectComponentListFromRepo).not.toHaveBeenCalled();
|
|
102
110
|
expect(mockedProjectAddPrompt).not.toHaveBeenCalled();
|
|
103
111
|
expect(mockedCloneGithubRepo).not.toHaveBeenCalled();
|
|
@@ -118,7 +126,7 @@ describe('lib/projects/add/legacyAddComponent', () => {
|
|
|
118
126
|
mockedGetProjectComponentListFromRepo.mockResolvedValue(mockComponentList);
|
|
119
127
|
mockedProjectAddPrompt.mockResolvedValue(mockPromptResponse);
|
|
120
128
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
121
|
-
await legacyAddComponent(mockArgs, projectDir, mockProjectConfig);
|
|
129
|
+
await legacyAddComponent(mockArgs, projectDir, mockProjectConfig, accountId);
|
|
122
130
|
expect(mockedGetProjectComponentListFromRepo).toHaveBeenCalledWith('v1');
|
|
123
131
|
expect(mockedProjectAddPrompt).toHaveBeenCalledWith(mockComponentList, mockArgs);
|
|
124
132
|
expect(mockedCloneGithubRepo).toHaveBeenCalled();
|
|
@@ -140,7 +148,7 @@ describe('lib/projects/add/legacyAddComponent', () => {
|
|
|
140
148
|
];
|
|
141
149
|
mockedFindProjectComponents.mockResolvedValue(mockComponents);
|
|
142
150
|
mockedGetProjectComponentListFromRepo.mockResolvedValue([]);
|
|
143
|
-
await expect(legacyAddComponent(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(commands.project.add.error.failedToFetchComponentList);
|
|
151
|
+
await expect(legacyAddComponent(mockArgs, projectDir, mockProjectConfig, accountId)).rejects.toThrow(commands.project.add.error.failedToFetchComponentList);
|
|
144
152
|
expect(mockedProjectAddPrompt).not.toHaveBeenCalled();
|
|
145
153
|
expect(mockedCloneGithubRepo).not.toHaveBeenCalled();
|
|
146
154
|
});
|
|
@@ -162,7 +170,7 @@ describe('lib/projects/add/legacyAddComponent', () => {
|
|
|
162
170
|
mockedFindProjectComponents.mockResolvedValue(mockComponents);
|
|
163
171
|
// @ts-expect-error Breaking stuff on purpose
|
|
164
172
|
mockedGetProjectComponentListFromRepo.mockResolvedValue(null);
|
|
165
|
-
await expect(legacyAddComponent(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(commands.project.add.error.failedToFetchComponentList);
|
|
173
|
+
await expect(legacyAddComponent(mockArgs, projectDir, mockProjectConfig, accountId)).rejects.toThrow(commands.project.add.error.failedToFetchComponentList);
|
|
166
174
|
expect(mockedProjectAddPrompt).not.toHaveBeenCalled();
|
|
167
175
|
expect(mockedCloneGithubRepo).not.toHaveBeenCalled();
|
|
168
176
|
});
|
|
@@ -196,9 +204,44 @@ describe('lib/projects/add/legacyAddComponent', () => {
|
|
|
196
204
|
mockedGetProjectComponentListFromRepo.mockResolvedValue(mockComponentList);
|
|
197
205
|
mockedProjectAddPrompt.mockResolvedValue(mockPromptResponse);
|
|
198
206
|
mockedCloneGithubRepo.mockRejectedValue(new Error('Clone failed'));
|
|
199
|
-
await expect(legacyAddComponent(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(commands.project.add.error.failedToDownloadComponent);
|
|
207
|
+
await expect(legacyAddComponent(mockArgs, projectDir, mockProjectConfig, accountId)).rejects.toThrow(commands.project.add.error.failedToDownloadComponent);
|
|
200
208
|
expect(mockedCloneGithubRepo).toHaveBeenCalled();
|
|
201
209
|
expect(mockedLogger.success).not.toHaveBeenCalled();
|
|
202
210
|
});
|
|
211
|
+
it('calls trackCommandUsage with correct component type', async () => {
|
|
212
|
+
const mockComponents = [
|
|
213
|
+
{
|
|
214
|
+
type: ComponentTypes.PrivateApp,
|
|
215
|
+
config: {
|
|
216
|
+
name: 'private-app',
|
|
217
|
+
description: '',
|
|
218
|
+
uid: '',
|
|
219
|
+
scopes: [],
|
|
220
|
+
public: false,
|
|
221
|
+
},
|
|
222
|
+
runnable: true,
|
|
223
|
+
path: '/path/to/private-app',
|
|
224
|
+
},
|
|
225
|
+
];
|
|
226
|
+
const mockComponentList = [
|
|
227
|
+
{ label: 'Card Component', path: 'card-component', type: 'card' },
|
|
228
|
+
];
|
|
229
|
+
const mockPromptResponse = {
|
|
230
|
+
name: 'new-card',
|
|
231
|
+
componentTemplate: {
|
|
232
|
+
label: 'Card Component',
|
|
233
|
+
path: 'card-template-path',
|
|
234
|
+
type: 'card',
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
mockedFindProjectComponents.mockResolvedValue(mockComponents);
|
|
238
|
+
mockedGetProjectComponentListFromRepo.mockResolvedValue(mockComponentList);
|
|
239
|
+
mockedProjectAddPrompt.mockResolvedValue(mockPromptResponse);
|
|
240
|
+
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
241
|
+
await legacyAddComponent(mockArgs, projectDir, mockProjectConfig, accountId);
|
|
242
|
+
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
243
|
+
type: 'card',
|
|
244
|
+
}, accountId);
|
|
245
|
+
});
|
|
203
246
|
});
|
|
204
247
|
});
|
|
@@ -7,6 +7,7 @@ import { projectAddPromptV3 } from '../../../prompts/projectAddPrompt.js';
|
|
|
7
7
|
import { cloneGithubRepo } from '@hubspot/local-dev-lib/github';
|
|
8
8
|
import { logger } from '@hubspot/local-dev-lib/logger';
|
|
9
9
|
import { getProjectMetadata } from '@hubspot/project-parsing-lib/src/lib/project.js';
|
|
10
|
+
import { trackCommandUsage } from '../../../usageTracking.js';
|
|
10
11
|
import { commands } from '../../../../lang/en.js';
|
|
11
12
|
vi.mock('fs');
|
|
12
13
|
vi.mock('../../../prompts/promptUtils');
|
|
@@ -16,6 +17,7 @@ vi.mock('../../../prompts/projectAddPrompt');
|
|
|
16
17
|
vi.mock('@hubspot/local-dev-lib/github');
|
|
17
18
|
vi.mock('@hubspot/local-dev-lib/logger');
|
|
18
19
|
vi.mock('@hubspot/project-parsing-lib/src/lib/project');
|
|
20
|
+
vi.mock('../../../usageTracking');
|
|
19
21
|
const mockedFs = vi.mocked(fs);
|
|
20
22
|
const mockedGetConfigForPlatformVersion = vi.mocked(getConfigForPlatformVersion);
|
|
21
23
|
const mockedConfirmPrompt = vi.mocked(confirmPrompt);
|
|
@@ -24,14 +26,20 @@ const mockedProjectAddPromptV3 = vi.mocked(projectAddPromptV3);
|
|
|
24
26
|
const mockedCloneGithubRepo = vi.mocked(cloneGithubRepo);
|
|
25
27
|
const mockedLogger = vi.mocked(logger);
|
|
26
28
|
const mockedGetProjectMetadata = vi.mocked(getProjectMetadata);
|
|
29
|
+
const mockedTrackCommandUsage = vi.mocked(trackCommandUsage);
|
|
27
30
|
describe('lib/projects/add/v3AddComponent', () => {
|
|
28
31
|
const mockProjectConfig = {
|
|
29
32
|
name: 'test-project',
|
|
30
33
|
srcDir: 'src',
|
|
31
34
|
platformVersion: 'v3',
|
|
32
35
|
};
|
|
33
|
-
const mockArgs = {
|
|
36
|
+
const mockArgs = {
|
|
37
|
+
name: 'test-component',
|
|
38
|
+
type: 'module',
|
|
39
|
+
derivedAccountId: 1234,
|
|
40
|
+
};
|
|
34
41
|
const projectDir = '/path/to/project';
|
|
42
|
+
const mockAccountId = 123;
|
|
35
43
|
const mockComponentTemplate = {
|
|
36
44
|
label: 'Test Component',
|
|
37
45
|
path: 'test-component',
|
|
@@ -62,6 +70,7 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
62
70
|
authType: 'oauth',
|
|
63
71
|
distribution: 'private',
|
|
64
72
|
});
|
|
73
|
+
mockedTrackCommandUsage.mockResolvedValue();
|
|
65
74
|
});
|
|
66
75
|
describe('v3AddComponent()', () => {
|
|
67
76
|
it('successfully adds a component when app already exists', async () => {
|
|
@@ -79,10 +88,13 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
79
88
|
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
80
89
|
mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
|
|
81
90
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
82
|
-
await v3AddComponent(mockArgs, projectDir, mockProjectConfig);
|
|
91
|
+
await v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
83
92
|
expect(mockedGetConfigForPlatformVersion).toHaveBeenCalledWith('v3');
|
|
84
93
|
expect(mockedGetProjectMetadata).toHaveBeenCalledWith('/path/to/project/src');
|
|
85
94
|
expect(mockedProjectAddPromptV3).toHaveBeenCalled();
|
|
95
|
+
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
96
|
+
type: 'module',
|
|
97
|
+
}, mockAccountId);
|
|
86
98
|
expect(mockedCloneGithubRepo).toHaveBeenCalledWith(expect.any(String), projectDir, expect.objectContaining({
|
|
87
99
|
sourceDir: ['v3/test-component'],
|
|
88
100
|
hideLogs: true,
|
|
@@ -106,8 +118,11 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
106
118
|
mockedConfirmPrompt.mockResolvedValue(true);
|
|
107
119
|
mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
|
|
108
120
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
109
|
-
await v3AddComponent(mockArgs, projectDir, mockProjectConfig);
|
|
121
|
+
await v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
110
122
|
expect(mockedCreateV3App).toHaveBeenCalled();
|
|
123
|
+
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
124
|
+
type: 'module',
|
|
125
|
+
}, mockAccountId);
|
|
111
126
|
expect(mockedCloneGithubRepo).toHaveBeenCalledWith(expect.any(String), projectDir, expect.objectContaining({
|
|
112
127
|
sourceDir: ['v3/test-component', 'v3/app-template'],
|
|
113
128
|
}));
|
|
@@ -132,8 +147,11 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
132
147
|
mockedConfirmPrompt.mockResolvedValue(true);
|
|
133
148
|
mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
|
|
134
149
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
135
|
-
await v3AddComponent(mockArgs, projectDir, mockProjectConfig);
|
|
150
|
+
await v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
136
151
|
expect(mockedCreateV3App).not.toHaveBeenCalled();
|
|
152
|
+
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
153
|
+
type: '',
|
|
154
|
+
}, mockAccountId);
|
|
137
155
|
expect(mockedCloneGithubRepo).not.toHaveBeenCalled();
|
|
138
156
|
});
|
|
139
157
|
it('throws an error when app count exceeds maximum', async () => {
|
|
@@ -146,7 +164,7 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
146
164
|
};
|
|
147
165
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
148
166
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadataMaxApps);
|
|
149
|
-
await expect(v3AddComponent(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow('This project currently has the maximum number of apps: 1');
|
|
167
|
+
await expect(v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId)).rejects.toThrow('This project currently has the maximum number of apps: 1');
|
|
150
168
|
});
|
|
151
169
|
it('throws an error when components list is empty', async () => {
|
|
152
170
|
const mockEmptyConfig = {
|
|
@@ -154,7 +172,7 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
154
172
|
parentComponents: [],
|
|
155
173
|
};
|
|
156
174
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockEmptyConfig);
|
|
157
|
-
await expect(v3AddComponent(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(commands.project.add.error.failedToFetchComponentList);
|
|
175
|
+
await expect(v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId)).rejects.toThrow(commands.project.add.error.failedToFetchComponentList);
|
|
158
176
|
});
|
|
159
177
|
it('throws an error when app meta file cannot be parsed', async () => {
|
|
160
178
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
@@ -162,7 +180,7 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
162
180
|
mockedFs.readFileSync.mockImplementation(() => {
|
|
163
181
|
throw new Error('File read error');
|
|
164
182
|
});
|
|
165
|
-
await expect(v3AddComponent(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow('Unable to parse app file');
|
|
183
|
+
await expect(v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId)).rejects.toThrow('Unable to parse app file');
|
|
166
184
|
});
|
|
167
185
|
it('throws an error when cloning fails', async () => {
|
|
168
186
|
const mockAppMeta = {
|
|
@@ -179,7 +197,123 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
179
197
|
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
180
198
|
mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
|
|
181
199
|
mockedCloneGithubRepo.mockRejectedValue(new Error('Clone failed'));
|
|
182
|
-
await expect(v3AddComponent(mockArgs, projectDir, mockProjectConfig)).rejects.toThrow(commands.project.add.error.failedToDownloadComponent);
|
|
200
|
+
await expect(v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId)).rejects.toThrow(commands.project.add.error.failedToDownloadComponent);
|
|
201
|
+
});
|
|
202
|
+
it('should track usage with multiple component types', async () => {
|
|
203
|
+
const mockAppMeta = {
|
|
204
|
+
config: {
|
|
205
|
+
distribution: 'private',
|
|
206
|
+
auth: { type: 'oauth' },
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
const mockSecondComponentTemplate = {
|
|
210
|
+
label: 'Test Card',
|
|
211
|
+
path: 'test-card',
|
|
212
|
+
type: 'card',
|
|
213
|
+
supportedAuthTypes: ['oauth'],
|
|
214
|
+
supportedDistributions: ['private'],
|
|
215
|
+
};
|
|
216
|
+
const mockPromptResponse = {
|
|
217
|
+
componentTemplate: [mockComponentTemplate, mockSecondComponentTemplate],
|
|
218
|
+
};
|
|
219
|
+
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
220
|
+
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
|
|
221
|
+
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
222
|
+
mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
|
|
223
|
+
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
224
|
+
await v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
225
|
+
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
226
|
+
type: 'module,card',
|
|
227
|
+
}, mockAccountId);
|
|
228
|
+
});
|
|
229
|
+
it('should track usage with empty type when no components are selected', async () => {
|
|
230
|
+
const mockProjectMetadataNoApps = {
|
|
231
|
+
hsMetaFiles: [],
|
|
232
|
+
components: {
|
|
233
|
+
app: {
|
|
234
|
+
count: 1,
|
|
235
|
+
maxCount: 1,
|
|
236
|
+
hsMetaFiles: ['/path/to/app.meta.json'],
|
|
237
|
+
},
|
|
238
|
+
module: { count: 0, maxCount: 5, hsMetaFiles: [] },
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
const mockPromptResponse = {
|
|
242
|
+
componentTemplate: [],
|
|
243
|
+
};
|
|
244
|
+
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
245
|
+
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadataNoApps);
|
|
246
|
+
mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
|
|
247
|
+
await v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
248
|
+
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
249
|
+
type: '',
|
|
250
|
+
}, mockAccountId);
|
|
251
|
+
});
|
|
252
|
+
it('should track usage with cliSelector when available', async () => {
|
|
253
|
+
const mockAppMeta = {
|
|
254
|
+
config: {
|
|
255
|
+
distribution: 'private',
|
|
256
|
+
auth: { type: 'oauth' },
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
const mockComponentTemplateWithCliSelector = {
|
|
260
|
+
label: 'Workflow Action Tool',
|
|
261
|
+
path: 'workflow-action-tool',
|
|
262
|
+
type: 'workflow-action',
|
|
263
|
+
cliSelector: 'workflow-action-tool',
|
|
264
|
+
supportedAuthTypes: ['oauth'],
|
|
265
|
+
supportedDistributions: ['private'],
|
|
266
|
+
};
|
|
267
|
+
const mockPromptResponse = {
|
|
268
|
+
componentTemplate: [mockComponentTemplateWithCliSelector],
|
|
269
|
+
};
|
|
270
|
+
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
271
|
+
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
|
|
272
|
+
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
273
|
+
mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
|
|
274
|
+
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
275
|
+
await v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
276
|
+
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
277
|
+
type: 'workflow-action-tool',
|
|
278
|
+
}, mockAccountId);
|
|
279
|
+
});
|
|
280
|
+
it('should track usage with cliSelector for multiple components', async () => {
|
|
281
|
+
const mockAppMeta = {
|
|
282
|
+
config: {
|
|
283
|
+
distribution: 'private',
|
|
284
|
+
auth: { type: 'oauth' },
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
const mockComponentWithCliSelector = {
|
|
288
|
+
label: 'Workflow Action Tool',
|
|
289
|
+
path: 'workflow-action-tool',
|
|
290
|
+
type: 'workflow-action',
|
|
291
|
+
cliSelector: 'workflow-action-tool',
|
|
292
|
+
supportedAuthTypes: ['oauth'],
|
|
293
|
+
supportedDistributions: ['private'],
|
|
294
|
+
};
|
|
295
|
+
const mockComponentWithoutCliSelector = {
|
|
296
|
+
label: 'Regular Module',
|
|
297
|
+
path: 'module',
|
|
298
|
+
type: 'module',
|
|
299
|
+
supportedAuthTypes: ['oauth'],
|
|
300
|
+
supportedDistributions: ['private'],
|
|
301
|
+
};
|
|
302
|
+
const mockPromptResponse = {
|
|
303
|
+
componentTemplate: [
|
|
304
|
+
mockComponentWithCliSelector,
|
|
305
|
+
mockComponentWithoutCliSelector,
|
|
306
|
+
],
|
|
307
|
+
};
|
|
308
|
+
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
309
|
+
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
|
|
310
|
+
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
311
|
+
mockedProjectAddPromptV3.mockResolvedValue(mockPromptResponse);
|
|
312
|
+
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
313
|
+
await v3AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
314
|
+
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
315
|
+
type: 'workflow-action-tool,module',
|
|
316
|
+
}, mockAccountId);
|
|
183
317
|
});
|
|
184
318
|
});
|
|
185
319
|
});
|
|
@@ -2,4 +2,4 @@ import { ProjectConfig } from '../../../types/Projects.js';
|
|
|
2
2
|
export declare function legacyAddComponent(args: {
|
|
3
3
|
name?: string;
|
|
4
4
|
type?: string;
|
|
5
|
-
}, projectDir: string, projectConfig: ProjectConfig): Promise<void>;
|
|
5
|
+
}, projectDir: string, projectConfig: ProjectConfig, derivedAccountId: number): Promise<void>;
|
|
@@ -8,7 +8,8 @@ import path from 'path';
|
|
|
8
8
|
import { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, DEFAULT_PROJECT_TEMPLATE_BRANCH, } from '../../constants.js';
|
|
9
9
|
import { cloneGithubRepo } from '@hubspot/local-dev-lib/github';
|
|
10
10
|
import { uiLogger } from '../../ui/logger.js';
|
|
11
|
-
|
|
11
|
+
import { trackCommandUsage } from '../../usageTracking.js';
|
|
12
|
+
export async function legacyAddComponent(args, projectDir, projectConfig, derivedAccountId) {
|
|
12
13
|
// We currently only support adding private apps to projects
|
|
13
14
|
let projectContainsPublicApp = false;
|
|
14
15
|
try {
|
|
@@ -27,6 +28,9 @@ export async function legacyAddComponent(args, projectDir, projectConfig) {
|
|
|
27
28
|
throw new Error(commands.project.add.error.failedToFetchComponentList);
|
|
28
29
|
}
|
|
29
30
|
const projectAddPromptResponse = await projectAddPrompt(components, args);
|
|
31
|
+
trackCommandUsage('project-add', {
|
|
32
|
+
type: projectAddPromptResponse.componentTemplate.type,
|
|
33
|
+
}, derivedAccountId);
|
|
30
34
|
try {
|
|
31
35
|
const componentPath = path.join(projectDir, projectConfig.srcDir, projectAddPromptResponse.name);
|
|
32
36
|
await cloneGithubRepo(HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, componentPath, {
|
|
@@ -5,4 +5,5 @@ export declare function v3AddComponent(args: {
|
|
|
5
5
|
features?: string[];
|
|
6
6
|
auth?: string;
|
|
7
7
|
distribution?: string;
|
|
8
|
-
|
|
8
|
+
derivedAccountId: number;
|
|
9
|
+
}, projectDir: string, projectConfig: ProjectConfig, accountId: number): Promise<void>;
|
|
@@ -6,13 +6,14 @@ import path from 'path';
|
|
|
6
6
|
import fs from 'fs';
|
|
7
7
|
import { projectAddPromptV3 } from '../../prompts/projectAddPrompt.js';
|
|
8
8
|
import { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, DEFAULT_PROJECT_TEMPLATE_BRANCH, } from '../../constants.js';
|
|
9
|
-
import { handleComponentCollision } from '../components.js';
|
|
9
|
+
import { updateHsMetaFilesWithAutoGeneratedFields, handleComponentCollision, } from '../components.js';
|
|
10
10
|
import { getProjectMetadata, } from '@hubspot/project-parsing-lib/src/lib/project.js';
|
|
11
11
|
import { AppKey } from '@hubspot/project-parsing-lib/src/lib/constants.js';
|
|
12
12
|
import { cloneGithubRepo } from '@hubspot/local-dev-lib/github';
|
|
13
13
|
import { debugError } from '../../errorHandlers/index.js';
|
|
14
14
|
import { uiLogger } from '../../ui/logger.js';
|
|
15
|
-
|
|
15
|
+
import { trackCommandUsage } from '../../usageTracking.js';
|
|
16
|
+
export async function v3AddComponent(args, projectDir, projectConfig, accountId) {
|
|
16
17
|
uiLogger.log(commands.project.add.creatingComponent(projectConfig.name));
|
|
17
18
|
const config = await getConfigForPlatformVersion(projectConfig.platformVersion);
|
|
18
19
|
const { components, parentComponents } = config;
|
|
@@ -20,10 +21,10 @@ export async function v3AddComponent(args, projectDir, projectConfig) {
|
|
|
20
21
|
throw new Error(commands.project.add.error.failedToFetchComponentList);
|
|
21
22
|
}
|
|
22
23
|
const projectSrcDirectory = path.join(projectDir, projectConfig.srcDir);
|
|
23
|
-
const
|
|
24
|
+
const currentProjectMetadata = await getProjectMetadata(projectSrcDirectory);
|
|
24
25
|
let derivedAuthType;
|
|
25
26
|
let derivedDistribution;
|
|
26
|
-
const appsMetadata =
|
|
27
|
+
const appsMetadata = currentProjectMetadata.components[AppKey];
|
|
27
28
|
const shouldCreateApp = appsMetadata.count === 0;
|
|
28
29
|
if (shouldCreateApp) {
|
|
29
30
|
const { authType, distribution } = await createV3App(args.auth, args.distribution);
|
|
@@ -45,8 +46,12 @@ export async function v3AddComponent(args, projectDir, projectConfig) {
|
|
|
45
46
|
derivedDistribution = apps[0].config?.distribution;
|
|
46
47
|
derivedAuthType = apps[0].config?.auth?.type;
|
|
47
48
|
}
|
|
48
|
-
const componentTemplateChoices = calculateComponentTemplateChoices(components, derivedAuthType, derivedDistribution,
|
|
49
|
+
const componentTemplateChoices = await calculateComponentTemplateChoices(components, derivedAuthType, derivedDistribution, args.derivedAccountId, currentProjectMetadata);
|
|
49
50
|
const projectAddPromptResponse = await projectAddPromptV3(componentTemplateChoices, args.features);
|
|
51
|
+
const componentTypes = projectAddPromptResponse.componentTemplate?.map(componentTemplate => componentTemplate.cliSelector || componentTemplate.type);
|
|
52
|
+
await trackCommandUsage('project-add', {
|
|
53
|
+
type: componentTypes?.join(','),
|
|
54
|
+
}, accountId);
|
|
50
55
|
try {
|
|
51
56
|
const components = projectAddPromptResponse.componentTemplate?.map((componentTemplate) => {
|
|
52
57
|
return path.join(projectConfig.platformVersion, componentTemplate.path);
|
|
@@ -71,6 +76,18 @@ export async function v3AddComponent(args, projectDir, projectConfig) {
|
|
|
71
76
|
branch: DEFAULT_PROJECT_TEMPLATE_BRANCH,
|
|
72
77
|
handleCollision: handleComponentCollision,
|
|
73
78
|
});
|
|
79
|
+
const updatedProjectMetadata = await getProjectMetadata(projectSrcDirectory);
|
|
80
|
+
const newHsMetaFiles = updatedProjectMetadata.hsMetaFiles.filter(hsMetaFile => !currentProjectMetadata.hsMetaFiles.includes(hsMetaFile));
|
|
81
|
+
const existingUids = currentProjectMetadata.hsMetaFiles.map(hsMetaFile => {
|
|
82
|
+
try {
|
|
83
|
+
const { uid } = JSON.parse(fs.readFileSync(hsMetaFile, 'utf8'));
|
|
84
|
+
return uid;
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
return '';
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
updateHsMetaFilesWithAutoGeneratedFields(projectConfig.name, newHsMetaFiles, existingUids);
|
|
74
91
|
uiLogger.success(commands.project.add.success(projectAddPromptResponse.componentTemplate
|
|
75
92
|
.map(template => `'${template.label}'`)
|
|
76
93
|
.join(', '), projectAddPromptResponse.componentTemplate.length > 1));
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { Collision } from '@hubspot/local-dev-lib/types/Archive';
|
|
2
2
|
export declare function handleComponentCollision({ dest, src, collisions }: Collision): void;
|
|
3
|
+
export declare function updateHsMetaFilesWithAutoGeneratedFields(projectName: string, hsMetaFilePaths: string[], existingUids?: string[]): void;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import fs from 'fs';
|
|
3
|
-
import { metafileExtension } from '@hubspot/project-parsing-lib';
|
|
3
|
+
import { coerceToValidUid, metafileExtension, } from '@hubspot/project-parsing-lib';
|
|
4
|
+
import { uiLogger } from '../ui/logger.js';
|
|
5
|
+
import { AppKey } from '@hubspot/project-parsing-lib/src/lib/constants.js';
|
|
6
|
+
import { lib } from '../../lang/en.js';
|
|
4
7
|
// Handles a collision between component source files
|
|
5
8
|
export function handleComponentCollision({ dest, src, collisions }) {
|
|
6
9
|
const hsMetaFiles = [];
|
|
@@ -74,3 +77,26 @@ function handlePackageJsonCollisions(dest, src, packageJsonFiles) {
|
|
|
74
77
|
fs.writeFileSync(path.join(dest, file), JSON.stringify(existingPackageJsonContents, null, 2));
|
|
75
78
|
});
|
|
76
79
|
}
|
|
80
|
+
export function updateHsMetaFilesWithAutoGeneratedFields(projectName, hsMetaFilePaths, existingUids = []) {
|
|
81
|
+
uiLogger.log('');
|
|
82
|
+
uiLogger.log(lib.projects.updateHsMetaFilesWithAutoGeneratedFields.header);
|
|
83
|
+
for (const hsMetaFile of hsMetaFilePaths) {
|
|
84
|
+
const component = JSON.parse(fs.readFileSync(hsMetaFile).toString());
|
|
85
|
+
let uid = coerceToValidUid(`${component.type}-${projectName}`) || component.uid;
|
|
86
|
+
if (existingUids.includes(uid)) {
|
|
87
|
+
uid =
|
|
88
|
+
coerceToValidUid(`${component.type}-${Date.now()}-${projectName}`) ||
|
|
89
|
+
component.uid;
|
|
90
|
+
}
|
|
91
|
+
component.uid = uid;
|
|
92
|
+
if (component.type === AppKey && component.config) {
|
|
93
|
+
component.config.name = `${projectName}-Application`;
|
|
94
|
+
uiLogger.log(lib.projects.updateHsMetaFilesWithAutoGeneratedFields.applicationLog(component.type, component.uid, component.config.name));
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
uiLogger.log(lib.projects.updateHsMetaFilesWithAutoGeneratedFields.componentLog(component.type, component.uid));
|
|
98
|
+
}
|
|
99
|
+
fs.writeFileSync(hsMetaFile, JSON.stringify(component, null, 2));
|
|
100
|
+
}
|
|
101
|
+
uiLogger.log('');
|
|
102
|
+
}
|