@hubspot/cli 7.8.12-experimental.1 → 7.9.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/__tests__/cms.test.js +44 -1
- package/commands/__tests__/customObject.test.js +22 -1
- package/commands/__tests__/project.test.js +2 -0
- package/commands/account/auth.js +1 -0
- package/commands/auth.js +1 -0
- package/commands/{__tests__/remove.test.js → cms/__tests__/delete.test.js} +8 -8
- package/commands/{__tests__ → cms/__tests__}/fetch.test.js +3 -3
- package/commands/{__tests__ → cms/__tests__}/function.test.js +7 -3
- package/commands/{__tests__ → cms/__tests__}/lint.test.js +3 -3
- package/commands/{__tests__ → cms/__tests__}/list.test.js +3 -3
- package/commands/{__tests__ → cms/__tests__}/mv.test.js +3 -3
- package/commands/{__tests__ → cms/__tests__}/theme.test.js +9 -2
- package/commands/cms/app/create.d.ts +9 -0
- package/commands/cms/app/create.js +82 -0
- package/commands/cms/app.d.ts +3 -0
- package/commands/cms/app.js +17 -0
- package/commands/cms/delete.d.ts +6 -0
- package/commands/cms/delete.js +43 -0
- package/commands/cms/fetch.d.ts +12 -0
- package/commands/cms/fetch.js +79 -0
- package/commands/{__tests__ → cms/function/__tests__}/logs.test.js +4 -5
- package/commands/cms/function/create.d.ts +12 -0
- package/commands/cms/function/create.js +84 -0
- package/commands/cms/function/deploy.d.ts +6 -0
- package/commands/cms/function/deploy.js +89 -0
- package/commands/cms/function/list.d.ts +6 -0
- package/commands/cms/function/list.js +60 -0
- package/commands/cms/function/logs.d.ts +10 -0
- package/commands/cms/function/logs.js +135 -0
- package/commands/cms/function/server.d.ts +10 -0
- package/commands/cms/function/server.js +69 -0
- package/commands/cms/function.d.ts +3 -0
- package/commands/cms/function.js +27 -0
- package/commands/cms/lint.d.ts +6 -0
- package/commands/cms/lint.js +83 -0
- package/commands/cms/list.d.ts +6 -0
- package/commands/cms/list.js +96 -0
- package/commands/cms/module/create.d.ts +11 -0
- package/commands/cms/module/create.js +84 -0
- package/commands/cms/module/marketplace-validate.d.ts +6 -0
- package/commands/cms/module/marketplace-validate.js +45 -0
- package/commands/cms/module.d.ts +3 -0
- package/commands/cms/module.js +17 -0
- package/commands/cms/mv.d.ts +7 -0
- package/commands/cms/mv.js +60 -0
- package/commands/cms/template/create.d.ts +9 -0
- package/commands/cms/template/create.js +72 -0
- package/commands/cms/template.d.ts +3 -0
- package/commands/cms/template.js +17 -0
- package/commands/{theme → cms/theme}/__tests__/marketplace-validate.test.js +2 -2
- package/commands/{theme → cms/theme}/__tests__/preview.test.js +2 -2
- package/commands/cms/theme/create.d.ts +6 -0
- package/commands/cms/theme/create.js +58 -0
- package/commands/cms/theme/generate-selectors.d.ts +6 -0
- package/commands/cms/theme/generate-selectors.js +171 -0
- package/commands/cms/theme/marketplace-validate.d.ts +6 -0
- package/commands/cms/theme/marketplace-validate.js +46 -0
- package/commands/cms/theme/preview.d.ts +12 -0
- package/commands/cms/theme/preview.js +224 -0
- package/commands/cms/theme.d.ts +3 -0
- package/commands/cms/theme.js +25 -0
- package/commands/cms/upload.d.ts +12 -0
- package/commands/cms/upload.js +212 -0
- package/commands/cms/watch.d.ts +14 -0
- package/commands/cms/watch.js +138 -0
- package/commands/cms/webpack/create.d.ts +6 -0
- package/commands/cms/webpack/create.js +58 -0
- package/commands/cms/webpack.d.ts +3 -0
- package/commands/cms/webpack.js +17 -0
- package/commands/cms.js +26 -0
- package/commands/create.js +4 -2
- package/commands/customObject/{schema/__tests__/create.test.js → __tests__/createSchema.test.js} +5 -5
- package/commands/customObject/{schema/__tests__/delete.test.js → __tests__/deleteSchema.test.js} +5 -5
- package/commands/customObject/{schema/__tests__/fetch-all.test.js → __tests__/fetch-all-schemas.test.js} +5 -5
- package/commands/customObject/{schema/__tests__/fetch.test.js → __tests__/fetchSchema.test.js} +5 -5
- package/commands/customObject/{schema/__tests__/list.test.js → __tests__/listSchemas.test.js} +5 -5
- package/commands/customObject/{schema/__tests__/update.test.js → __tests__/updateSchema.test.js} +5 -5
- package/commands/customObject/createSchema.d.ts +6 -0
- package/commands/customObject/createSchema.js +56 -0
- package/commands/customObject/deleteSchema.d.ts +7 -0
- package/commands/customObject/deleteSchema.js +69 -0
- package/commands/customObject/fetchAllSchemas.d.ts +6 -0
- package/commands/customObject/fetchAllSchemas.js +57 -0
- package/commands/customObject/fetchSchema.d.ts +7 -0
- package/commands/customObject/fetchSchema.js +67 -0
- package/commands/customObject/listSchemas.d.ts +4 -0
- package/commands/customObject/listSchemas.js +35 -0
- package/commands/customObject/schema/create.d.ts +4 -6
- package/commands/customObject/schema/create.js +13 -36
- package/commands/customObject/schema/delete.d.ts +4 -7
- package/commands/customObject/schema/delete.js +15 -50
- package/commands/customObject/schema/fetch-all.d.ts +4 -6
- package/commands/customObject/schema/fetch-all.js +14 -41
- package/commands/customObject/schema/fetch.d.ts +4 -7
- package/commands/customObject/schema/fetch.js +14 -49
- package/commands/customObject/schema/list.d.ts +4 -4
- package/commands/customObject/schema/list.js +10 -19
- package/commands/customObject/schema/update.d.ts +4 -7
- package/commands/customObject/schema/update.js +15 -50
- package/commands/customObject/schema.js +4 -2
- package/commands/customObject/updateSchema.d.ts +7 -0
- package/commands/customObject/updateSchema.js +71 -0
- package/commands/customObject.js +16 -1
- package/commands/feedback.js +1 -1
- package/commands/fetch.d.ts +4 -12
- package/commands/fetch.js +19 -46
- package/commands/function/deploy.d.ts +4 -6
- package/commands/function/deploy.js +14 -71
- package/commands/function/list.d.ts +4 -6
- package/commands/function/list.js +14 -40
- package/commands/function/server.d.ts +4 -10
- package/commands/function/server.js +22 -29
- package/commands/function.d.ts +2 -4
- package/commands/function.js +25 -14
- package/commands/lint.d.ts +4 -6
- package/commands/lint.js +13 -65
- package/commands/list.d.ts +4 -6
- package/commands/list.js +13 -74
- package/commands/logs.d.ts +4 -10
- package/commands/logs.js +24 -87
- package/commands/module/marketplace-validate.d.ts +4 -6
- package/commands/module/marketplace-validate.js +15 -27
- package/commands/module.d.ts +2 -2
- package/commands/module.js +17 -15
- package/commands/mv.d.ts +4 -7
- package/commands/mv.js +13 -39
- package/commands/project/__tests__/add.test.js +12 -12
- package/commands/project/__tests__/devUnifiedFlow.test.js +32 -0
- package/commands/project/__tests__/list.test.js +31 -0
- package/commands/project/__tests__/migrate.test.js +1 -0
- package/commands/project/add.d.ts +2 -2
- package/commands/project/add.js +3 -2
- package/commands/project/create.js +1 -1
- package/commands/project/dev/deprecatedFlow.js +2 -2
- package/commands/project/dev/index.js +5 -5
- package/commands/project/dev/unifiedFlow.js +8 -3
- package/commands/project/download.js +5 -2
- package/commands/project/installDeps.d.ts +2 -2
- package/commands/project/installDeps.js +1 -0
- package/commands/project/list.d.ts +4 -0
- package/commands/project/list.js +62 -0
- package/commands/project/migrate.js +5 -2
- package/commands/project.js +2 -0
- package/commands/remove.d.ts +4 -6
- package/commands/remove.js +12 -24
- package/commands/testAccount/create.js +2 -2
- package/commands/testAccount/delete.js +1 -1
- package/commands/theme/generate-selectors.d.ts +4 -6
- package/commands/theme/generate-selectors.js +14 -152
- package/commands/theme/marketplace-validate.d.ts +4 -6
- package/commands/theme/marketplace-validate.js +14 -25
- package/commands/theme/preview.d.ts +4 -12
- package/commands/theme/preview.js +18 -180
- package/commands/theme.d.ts +2 -2
- package/commands/theme.js +19 -13
- package/commands/upload.d.ts +4 -12
- package/commands/upload.js +19 -169
- package/commands/watch.d.ts +4 -14
- package/commands/watch.js +23 -88
- package/lang/en.d.ts +561 -425
- package/lang/en.js +563 -427
- package/lang/en.lyaml +2 -2
- package/lib/__tests__/buildAccount.test.js +2 -2
- package/lib/__tests__/http.test.js +40 -0
- package/lib/buildAccount.d.ts +2 -2
- package/lib/buildAccount.js +7 -7
- package/lib/configMigrate.js +88 -9
- package/lib/constants.d.ts +9 -0
- package/lib/constants.js +9 -0
- package/lib/generateSelectors.js +1 -1
- package/lib/http.d.ts +1 -0
- package/lib/http.js +26 -0
- package/lib/middleware/autoUpdateMiddleware.d.ts +2 -1
- package/lib/middleware/autoUpdateMiddleware.js +12 -2
- package/lib/middleware/commandTargetingUtils.d.ts +1 -1
- package/lib/middleware/commandTargetingUtils.js +16 -20
- package/lib/projects/__tests__/AppDevModeInterface.test.js +95 -109
- package/lib/projects/__tests__/DevServerManager.test.d.ts +1 -0
- package/lib/projects/__tests__/DevServerManager.test.js +183 -0
- package/lib/projects/__tests__/LocalDevProcess.test.js +6 -5
- package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +6 -6
- package/lib/projects/__tests__/UIExtensionsDevModeInterface.test.d.ts +1 -0
- package/lib/projects/__tests__/UIExtensionsDevModeInterface.test.js +161 -0
- package/lib/projects/__tests__/deploy.test.js +9 -9
- package/lib/projects/__tests__/upload.test.js +2 -2
- package/lib/projects/add/__tests__/v2AddComponent.test.d.ts +1 -0
- package/lib/projects/add/__tests__/{v3AddComponent.test.js → v2AddComponent.test.js} +35 -35
- package/lib/projects/add/{v3AddComponent.d.ts → v2AddComponent.d.ts} +1 -1
- package/lib/projects/add/{v3AddComponent.js → v2AddComponent.js} +5 -5
- package/lib/projects/create/__tests__/v2.test.d.ts +1 -0
- package/lib/projects/create/__tests__/{v3.test.js → v2.test.js} +2 -2
- package/lib/projects/create/index.js +2 -2
- package/lib/projects/create/{v3.d.ts → v2.d.ts} +3 -3
- package/lib/projects/create/{v3.js → v2.js} +3 -3
- package/lib/projects/deploy.d.ts +1 -1
- package/lib/projects/deploy.js +2 -2
- package/lib/projects/localDev/AppDevModeInterface.d.ts +10 -3
- package/lib/projects/localDev/AppDevModeInterface.js +132 -105
- package/lib/projects/localDev/DevServerManager.d.ts +10 -29
- package/lib/projects/localDev/DevServerManager.js +20 -76
- package/lib/projects/localDev/DevServerManager_DEPRECATED.d.ts +40 -0
- package/lib/projects/localDev/DevServerManager_DEPRECATED.js +120 -0
- package/lib/projects/localDev/{LocalDevManager.js → LocalDevManager_DEPRECATED.js} +6 -6
- package/lib/projects/localDev/LocalDevProcess.js +3 -2
- package/lib/projects/localDev/LocalDevState.d.ts +3 -0
- package/lib/projects/localDev/LocalDevState.js +9 -0
- package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +4 -0
- package/lib/projects/localDev/LocalDevWebsocketServer.js +39 -6
- package/lib/projects/localDev/UIExtensionsDevModeInterface.d.ts +13 -0
- package/lib/projects/localDev/UIExtensionsDevModeInterface.js +37 -0
- package/lib/projects/localDev/helpers/account.d.ts +1 -1
- package/lib/projects/localDev/helpers/account.js +2 -2
- package/lib/projects/localDev/helpers/process.d.ts +1 -0
- package/lib/projects/localDev/helpers/process.js +15 -0
- package/lib/projects/localDev/helpers/project.js +2 -3
- package/lib/projects/localDev/localDevWebsocketServerUtils.d.ts +3 -0
- package/lib/projects/localDev/localDevWebsocketServerUtils.js +9 -0
- package/lib/projects/urls.d.ts +0 -1
- package/lib/projects/urls.js +0 -3
- package/lib/prompts/__tests__/projectAddPrompt.test.js +10 -10
- package/lib/prompts/installAppPrompt.d.ts +1 -6
- package/lib/prompts/installAppPrompt.js +1 -6
- package/lib/prompts/projectAddPrompt.d.ts +2 -2
- package/lib/prompts/projectAddPrompt.js +1 -1
- package/lib/theme/__tests__/migrate.test.js +4 -4
- package/lib/ui/index.d.ts +2 -0
- package/lib/ui/index.js +8 -0
- package/lib/ui/uiMessages.d.ts +5 -0
- package/lib/ui/uiMessages.js +5 -0
- package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +2 -2
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +1 -1
- package/package.json +6 -5
- package/types/Cms.d.ts +6 -6
- package/lib/projects/localDev/DevServerManagerV2.d.ts +0 -22
- package/lib/projects/localDev/DevServerManagerV2.js +0 -81
- /package/commands/{customObject/schema → cms}/__tests__/delete.test.d.ts +0 -0
- /package/commands/{__tests__ → cms/__tests__}/fetch.test.d.ts +0 -0
- /package/commands/{__tests__ → cms/__tests__}/function.test.d.ts +0 -0
- /package/commands/{__tests__ → cms/__tests__}/lint.test.d.ts +0 -0
- /package/commands/{__tests__ → cms/__tests__}/list.test.d.ts +0 -0
- /package/commands/{__tests__ → cms/__tests__}/mv.test.d.ts +0 -0
- /package/commands/{__tests__ → cms/__tests__}/theme.test.d.ts +0 -0
- /package/commands/{__tests__ → cms/function/__tests__}/logs.test.d.ts +0 -0
- /package/commands/{theme → cms/theme}/__tests__/generate-selectors.test.d.ts +0 -0
- /package/commands/{theme → cms/theme}/__tests__/generate-selectors.test.js +0 -0
- /package/commands/{theme → cms/theme}/__tests__/marketplace-validate.test.d.ts +0 -0
- /package/commands/{theme → cms/theme}/__tests__/preview.test.d.ts +0 -0
- /package/commands/{__tests__/remove.test.d.ts → customObject/__tests__/createSchema.test.d.ts} +0 -0
- /package/commands/customObject/{schema/__tests__/create.test.d.ts → __tests__/deleteSchema.test.d.ts} +0 -0
- /package/commands/customObject/{schema/__tests__/fetch-all.test.d.ts → __tests__/fetch-all-schemas.test.d.ts} +0 -0
- /package/commands/customObject/{schema/__tests__/fetch.test.d.ts → __tests__/fetchSchema.test.d.ts} +0 -0
- /package/commands/customObject/{schema/__tests__/list.test.d.ts → __tests__/listSchemas.test.d.ts} +0 -0
- /package/commands/customObject/{schema/__tests__/update.test.d.ts → __tests__/updateSchema.test.d.ts} +0 -0
- /package/{lib/projects/add/__tests__/v3AddComponent.test.d.ts → commands/project/__tests__/list.test.d.ts} +0 -0
- /package/lib/{projects/create/__tests__/v3.test.d.ts → __tests__/http.test.d.ts} +0 -0
- /package/{commands/create → lib/cmsAssets}/api-sample.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/api-sample.js +0 -0
- /package/{commands/create → lib/cmsAssets}/app.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/app.js +0 -0
- /package/{commands/create → lib/cmsAssets}/function.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/function.js +0 -0
- /package/{commands/create → lib/cmsAssets}/index.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/index.js +0 -0
- /package/{commands/create → lib/cmsAssets}/module.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/module.js +0 -0
- /package/{commands/create → lib/cmsAssets}/react-app.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/react-app.js +0 -0
- /package/{commands/create → lib/cmsAssets}/template.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/template.js +0 -0
- /package/{commands/create → lib/cmsAssets}/vue-app.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/vue-app.js +0 -0
- /package/{commands/create → lib/cmsAssets}/webpack-serverless.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/webpack-serverless.js +0 -0
- /package/{commands/create → lib/cmsAssets}/website-theme.d.ts +0 -0
- /package/{commands/create → lib/cmsAssets}/website-theme.js +0 -0
- /package/lib/projects/localDev/{LocalDevManager.d.ts → LocalDevManager_DEPRECATED.d.ts} +0 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import UIExtensionsDevModeInterface from '../localDev/UIExtensionsDevModeInterface.js';
|
|
3
|
+
import LocalDevState from '../localDev/LocalDevState.js';
|
|
4
|
+
import { DevModeUnifiedInterface } from '@hubspot/ui-extensions-dev-server';
|
|
5
|
+
import { requestPorts } from '@hubspot/local-dev-lib/portManager';
|
|
6
|
+
import { logger } from '@hubspot/local-dev-lib/logger';
|
|
7
|
+
import { getHubSpotApiOrigin, getHubSpotWebsiteOrigin, } from '@hubspot/local-dev-lib/urls';
|
|
8
|
+
import { ENVIRONMENTS } from '@hubspot/local-dev-lib/constants/environments';
|
|
9
|
+
vi.mock('@hubspot/ui-extensions-dev-server', () => ({
|
|
10
|
+
DevModeUnifiedInterface: {
|
|
11
|
+
setup: vi.fn().mockResolvedValue(undefined),
|
|
12
|
+
start: vi.fn().mockResolvedValue(undefined),
|
|
13
|
+
fileChange: vi.fn().mockResolvedValue(undefined),
|
|
14
|
+
cleanup: vi.fn().mockResolvedValue(undefined),
|
|
15
|
+
},
|
|
16
|
+
}));
|
|
17
|
+
vi.mock('@hubspot/local-dev-lib/portManager', () => ({
|
|
18
|
+
requestPorts: vi.fn().mockResolvedValue({ 'test-port': 8080 }),
|
|
19
|
+
}));
|
|
20
|
+
vi.mock('@hubspot/local-dev-lib/urls', () => ({
|
|
21
|
+
getHubSpotApiOrigin: vi.fn().mockReturnValue('https://api.hubspot.com'),
|
|
22
|
+
getHubSpotWebsiteOrigin: vi.fn().mockReturnValue('https://app.hubspot.com'),
|
|
23
|
+
}));
|
|
24
|
+
describe('UIExtensionsDevModeInterface', () => {
|
|
25
|
+
let uiExtensionsInterface;
|
|
26
|
+
let mockLocalDevState;
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
vi.clearAllMocks();
|
|
29
|
+
vi.mocked(DevModeUnifiedInterface.setup).mockResolvedValue(undefined);
|
|
30
|
+
vi.mocked(DevModeUnifiedInterface.start).mockResolvedValue(undefined);
|
|
31
|
+
vi.mocked(DevModeUnifiedInterface.fileChange).mockResolvedValue(undefined);
|
|
32
|
+
vi.mocked(DevModeUnifiedInterface.cleanup).mockResolvedValue(undefined);
|
|
33
|
+
mockLocalDevState = new LocalDevState({
|
|
34
|
+
targetProjectAccountId: 123,
|
|
35
|
+
targetTestingAccountId: 456,
|
|
36
|
+
projectConfig: {
|
|
37
|
+
name: 'test-ui-extensions-project',
|
|
38
|
+
srcDir: 'src',
|
|
39
|
+
platformVersion: '1.0.0',
|
|
40
|
+
},
|
|
41
|
+
projectDir: '/test/ui-extensions-project',
|
|
42
|
+
projectData: {
|
|
43
|
+
name: 'test-ui-extensions-project',
|
|
44
|
+
id: 789,
|
|
45
|
+
createdAt: Date.now(),
|
|
46
|
+
deletedAt: 0,
|
|
47
|
+
isLocked: false,
|
|
48
|
+
portalId: 123,
|
|
49
|
+
updatedAt: Date.now(),
|
|
50
|
+
},
|
|
51
|
+
debug: false,
|
|
52
|
+
initialProjectNodes: {
|
|
53
|
+
'test-component': {
|
|
54
|
+
uid: 'test-component-uid',
|
|
55
|
+
componentType: 'UI_EXTENSION',
|
|
56
|
+
config: {
|
|
57
|
+
name: 'Test UI Extension',
|
|
58
|
+
type: 'card',
|
|
59
|
+
},
|
|
60
|
+
localDev: {
|
|
61
|
+
componentRoot: '/test/path',
|
|
62
|
+
componentConfigPath: '/test/path/config.json',
|
|
63
|
+
configUpdatedSinceLastUpload: false,
|
|
64
|
+
removed: false,
|
|
65
|
+
parsingErrors: [],
|
|
66
|
+
},
|
|
67
|
+
componentDeps: {},
|
|
68
|
+
metaFilePath: '/test/path',
|
|
69
|
+
files: [],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
initialProjectProfileData: {
|
|
73
|
+
testVariable: 'testValue',
|
|
74
|
+
},
|
|
75
|
+
profile: 'test',
|
|
76
|
+
env: ENVIRONMENTS.QA,
|
|
77
|
+
});
|
|
78
|
+
uiExtensionsInterface = new UIExtensionsDevModeInterface({
|
|
79
|
+
localDevState: mockLocalDevState,
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('constructor', () => {
|
|
83
|
+
it('should store the localDevState reference', () => {
|
|
84
|
+
expect(uiExtensionsInterface.localDevState).toBe(mockLocalDevState);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
describe('setup', () => {
|
|
88
|
+
it('should call DevModeUnifiedInterface.setup with correct parameters', async () => {
|
|
89
|
+
await uiExtensionsInterface.setup();
|
|
90
|
+
expect(DevModeUnifiedInterface.setup).toHaveBeenCalledWith({
|
|
91
|
+
components: mockLocalDevState.projectNodes,
|
|
92
|
+
profileData: mockLocalDevState.projectProfileData,
|
|
93
|
+
logger,
|
|
94
|
+
urls: {
|
|
95
|
+
api: 'https://api.hubspot.com',
|
|
96
|
+
web: 'https://app.hubspot.com',
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
it('should use correct URLs based on environment', async () => {
|
|
101
|
+
await uiExtensionsInterface.setup();
|
|
102
|
+
expect(getHubSpotApiOrigin).toHaveBeenCalledWith(mockLocalDevState.env);
|
|
103
|
+
expect(getHubSpotWebsiteOrigin).toHaveBeenCalledWith(mockLocalDevState.env);
|
|
104
|
+
});
|
|
105
|
+
it('should pass project nodes and profile data from state', async () => {
|
|
106
|
+
await uiExtensionsInterface.setup();
|
|
107
|
+
const setupCall = vi.mocked(DevModeUnifiedInterface.setup).mock
|
|
108
|
+
.calls[0][0];
|
|
109
|
+
expect(setupCall.components).toStrictEqual(mockLocalDevState.projectNodes);
|
|
110
|
+
expect(setupCall.profileData).toStrictEqual(mockLocalDevState.projectProfileData);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
describe('start', () => {
|
|
114
|
+
it('should call DevModeUnifiedInterface.start with correct parameters', async () => {
|
|
115
|
+
await uiExtensionsInterface.start();
|
|
116
|
+
expect(DevModeUnifiedInterface.start).toHaveBeenCalledWith({
|
|
117
|
+
accountId: mockLocalDevState.targetTestingAccountId,
|
|
118
|
+
projectConfig: mockLocalDevState.projectConfig,
|
|
119
|
+
requestPorts,
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
it('should use targetTestingAccountId from state', async () => {
|
|
123
|
+
await uiExtensionsInterface.start();
|
|
124
|
+
const startCall = vi.mocked(DevModeUnifiedInterface.start).mock
|
|
125
|
+
.calls[0][0];
|
|
126
|
+
expect(startCall.accountId).toBe(456); // targetTestingAccountId
|
|
127
|
+
});
|
|
128
|
+
it('should pass project config from state', async () => {
|
|
129
|
+
await uiExtensionsInterface.start();
|
|
130
|
+
const startCall = vi.mocked(DevModeUnifiedInterface.start).mock
|
|
131
|
+
.calls[0][0];
|
|
132
|
+
expect(startCall.projectConfig).toStrictEqual(mockLocalDevState.projectConfig);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
describe('fileChange', () => {
|
|
136
|
+
it('should call DevModeUnifiedInterface.fileChange with correct parameters', async () => {
|
|
137
|
+
const filePath = 'src/components/TestCard.tsx';
|
|
138
|
+
const event = 'change';
|
|
139
|
+
await uiExtensionsInterface.fileChange(filePath, event);
|
|
140
|
+
expect(DevModeUnifiedInterface.fileChange).toHaveBeenCalledWith(filePath, event);
|
|
141
|
+
});
|
|
142
|
+
it('should handle different file events', async () => {
|
|
143
|
+
const testCases = [
|
|
144
|
+
{ filePath: 'src/components/Card.tsx', event: 'add' },
|
|
145
|
+
{ filePath: 'src/styles/main.css', event: 'change' },
|
|
146
|
+
{ filePath: 'src/config.json', event: 'unlink' },
|
|
147
|
+
];
|
|
148
|
+
for (const testCase of testCases) {
|
|
149
|
+
await uiExtensionsInterface.fileChange(testCase.filePath, testCase.event);
|
|
150
|
+
expect(DevModeUnifiedInterface.fileChange).toHaveBeenCalledWith(testCase.filePath, testCase.event);
|
|
151
|
+
}
|
|
152
|
+
expect(DevModeUnifiedInterface.fileChange).toHaveBeenCalledTimes(3);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
describe('cleanup', () => {
|
|
156
|
+
it('should call DevModeUnifiedInterface.cleanup', async () => {
|
|
157
|
+
await uiExtensionsInterface.cleanup();
|
|
158
|
+
expect(DevModeUnifiedInterface.cleanup).toHaveBeenCalledWith();
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -99,7 +99,7 @@ describe('lib/projects/deploy', () => {
|
|
|
99
99
|
const targetAccountId = 12345;
|
|
100
100
|
const projectName = 'test-project';
|
|
101
101
|
const buildId = 5;
|
|
102
|
-
const
|
|
102
|
+
const useV2Api = true;
|
|
103
103
|
const force = false;
|
|
104
104
|
it('successfully deploys and returns deploy result', async () => {
|
|
105
105
|
const mockDeployResponseData = {
|
|
@@ -126,8 +126,8 @@ describe('lib/projects/deploy', () => {
|
|
|
126
126
|
data: mockDeployResponseData,
|
|
127
127
|
});
|
|
128
128
|
mockPollDeployStatus.mockResolvedValue(mockDeployResult);
|
|
129
|
-
const deploy = await handleProjectDeploy(targetAccountId, projectName, buildId,
|
|
130
|
-
expect(mockDeployProject).toHaveBeenCalledWith(targetAccountId, projectName, buildId,
|
|
129
|
+
const deploy = await handleProjectDeploy(targetAccountId, projectName, buildId, useV2Api, force);
|
|
130
|
+
expect(mockDeployProject).toHaveBeenCalledWith(targetAccountId, projectName, buildId, useV2Api, force);
|
|
131
131
|
expect(deploy).toEqual(mockDeployResult);
|
|
132
132
|
});
|
|
133
133
|
it('handles blocked deploy with warnings', async () => {
|
|
@@ -150,7 +150,7 @@ describe('lib/projects/deploy', () => {
|
|
|
150
150
|
mockDeployProject.mockResolvedValue({
|
|
151
151
|
data: mockBlockedResponse,
|
|
152
152
|
});
|
|
153
|
-
await handleProjectDeploy(targetAccountId, projectName, buildId,
|
|
153
|
+
await handleProjectDeploy(targetAccountId, projectName, buildId, useV2Api, force);
|
|
154
154
|
expect(mockUiLogger.warn).toHaveBeenCalledWith(commands.project.deploy.errors.deployWarningsHeader);
|
|
155
155
|
});
|
|
156
156
|
it('handles blocked deploy with errors (cannot be forced)', async () => {
|
|
@@ -173,7 +173,7 @@ describe('lib/projects/deploy', () => {
|
|
|
173
173
|
mockDeployProject.mockResolvedValue({
|
|
174
174
|
data: mockBlockedResponse,
|
|
175
175
|
});
|
|
176
|
-
await handleProjectDeploy(targetAccountId, projectName, buildId,
|
|
176
|
+
await handleProjectDeploy(targetAccountId, projectName, buildId, useV2Api, force);
|
|
177
177
|
expect(mockUiLogger.error).toHaveBeenCalledWith(commands.project.deploy.errors.deployBlockedHeader);
|
|
178
178
|
expect(mockUiLogger.log).toHaveBeenCalledWith(commands.project.deploy.errors.deployIssueComponentWarning('component-1', 'module', 'This is an error'));
|
|
179
179
|
});
|
|
@@ -192,19 +192,19 @@ describe('lib/projects/deploy', () => {
|
|
|
192
192
|
mockDeployProject.mockResolvedValue({
|
|
193
193
|
data: mockBlockedResponse,
|
|
194
194
|
});
|
|
195
|
-
await handleProjectDeploy(targetAccountId, projectName, buildId,
|
|
195
|
+
await handleProjectDeploy(targetAccountId, projectName, buildId, useV2Api, force);
|
|
196
196
|
expect(mockUiLogger.warn).toHaveBeenCalledWith(commands.project.deploy.errors.deployWarningsHeader);
|
|
197
197
|
expect(mockUiLogger.log).toHaveBeenCalledWith(commands.project.deploy.errors.deployIssueComponentGeneric('component-1', 'module'));
|
|
198
198
|
});
|
|
199
199
|
it('handles general deploy failure', async () => {
|
|
200
200
|
mockDeployProject.mockResolvedValue({ data: null });
|
|
201
|
-
const deploy = await handleProjectDeploy(targetAccountId, projectName, buildId,
|
|
201
|
+
const deploy = await handleProjectDeploy(targetAccountId, projectName, buildId, useV2Api, force);
|
|
202
202
|
expect(mockUiLogger.error).toHaveBeenCalledWith(commands.project.deploy.errors.deploy);
|
|
203
203
|
expect(deploy).toBeUndefined();
|
|
204
204
|
});
|
|
205
205
|
it('handles undefined deploy response', async () => {
|
|
206
206
|
mockDeployProject.mockResolvedValue({ data: undefined });
|
|
207
|
-
const deploy = await handleProjectDeploy(targetAccountId, projectName, buildId,
|
|
207
|
+
const deploy = await handleProjectDeploy(targetAccountId, projectName, buildId, useV2Api, force);
|
|
208
208
|
expect(mockUiLogger.error).toHaveBeenCalledWith(commands.project.deploy.errors.deploy);
|
|
209
209
|
expect(deploy).toBeUndefined();
|
|
210
210
|
});
|
|
@@ -221,7 +221,7 @@ describe('lib/projects/deploy', () => {
|
|
|
221
221
|
});
|
|
222
222
|
mockPollDeployStatus.mockResolvedValue({});
|
|
223
223
|
await handleProjectDeploy(targetAccountId, projectName, buildId, false, true);
|
|
224
|
-
expect(mockDeployProject).toHaveBeenCalledWith(targetAccountId, projectName, buildId, false, //
|
|
224
|
+
expect(mockDeployProject).toHaveBeenCalledWith(targetAccountId, projectName, buildId, false, // useV2Api
|
|
225
225
|
true // force
|
|
226
226
|
);
|
|
227
227
|
});
|
|
@@ -36,7 +36,7 @@ describe('lib/projects/upload', () => {
|
|
|
36
36
|
await expect(validateSourceDirectory(srcDir, projectConfig, tempDir)).rejects.toThrow(ProjectValidationError);
|
|
37
37
|
expect(walk).toHaveBeenCalledWith(srcDir, ['node_modules']);
|
|
38
38
|
});
|
|
39
|
-
it('should warn about legacy files in
|
|
39
|
+
it('should warn about legacy files in V2 projects', async () => {
|
|
40
40
|
vi.mocked(isV2Project).mockReturnValue(true);
|
|
41
41
|
const legacyFilePath = path.join(srcDir, 'app', 'serverless.json');
|
|
42
42
|
vi.mocked(walk).mockResolvedValue([legacyFilePath]);
|
|
@@ -67,7 +67,7 @@ describe('lib/projects/upload', () => {
|
|
|
67
67
|
await validateSourceDirectory(srcDir, projectConfig, tempDir);
|
|
68
68
|
expect(uiLogger.warn).not.toHaveBeenCalled();
|
|
69
69
|
});
|
|
70
|
-
it('should not warn about legacy files in non-
|
|
70
|
+
it('should not warn about legacy files in non-V2 projects', async () => {
|
|
71
71
|
vi.mocked(isV2Project).mockReturnValue(false);
|
|
72
72
|
projectConfig.platformVersion = '2025.1';
|
|
73
73
|
const filePaths = [
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import {
|
|
2
|
+
import { v2AddComponent } from '../v2AddComponent.js';
|
|
3
3
|
import { getConfigForPlatformVersion } from '../../create/legacy.js';
|
|
4
|
-
import {
|
|
4
|
+
import { createV2App } from '../../create/v2.js';
|
|
5
5
|
import { confirmPrompt } from '../../../prompts/promptUtils.js';
|
|
6
|
-
import {
|
|
6
|
+
import { projectAddPromptV2 } from '../../../prompts/projectAddPrompt.js';
|
|
7
7
|
import { cloneGithubRepo } from '@hubspot/local-dev-lib/github';
|
|
8
8
|
import { uiLogger } from '../../../ui/logger.js';
|
|
9
9
|
import { getProjectMetadata } from '@hubspot/project-parsing-lib/src/lib/project.js';
|
|
@@ -12,7 +12,7 @@ import { commands } from '../../../../lang/en.js';
|
|
|
12
12
|
vi.mock('fs');
|
|
13
13
|
vi.mock('../../../prompts/promptUtils');
|
|
14
14
|
vi.mock('../../create/legacy');
|
|
15
|
-
vi.mock('../../create/
|
|
15
|
+
vi.mock('../../create/v2');
|
|
16
16
|
vi.mock('../../../prompts/projectAddPrompt');
|
|
17
17
|
vi.mock('@hubspot/local-dev-lib/github');
|
|
18
18
|
vi.mock('../../../ui/logger.js');
|
|
@@ -21,17 +21,17 @@ vi.mock('../../../usageTracking');
|
|
|
21
21
|
const mockedFs = vi.mocked(fs);
|
|
22
22
|
const mockedGetConfigForPlatformVersion = vi.mocked(getConfigForPlatformVersion);
|
|
23
23
|
const mockedConfirmPrompt = vi.mocked(confirmPrompt);
|
|
24
|
-
const
|
|
25
|
-
const
|
|
24
|
+
const mockedCreateV2App = vi.mocked(createV2App);
|
|
25
|
+
const mockedProjectAddPromptV2 = vi.mocked(projectAddPromptV2);
|
|
26
26
|
const mockedCloneGithubRepo = vi.mocked(cloneGithubRepo);
|
|
27
27
|
const mockedUiLogger = vi.mocked(uiLogger);
|
|
28
28
|
const mockedGetProjectMetadata = vi.mocked(getProjectMetadata);
|
|
29
29
|
const mockedTrackCommandUsage = vi.mocked(trackCommandUsage);
|
|
30
|
-
describe('lib/projects/add/
|
|
30
|
+
describe('lib/projects/add/v2AddComponent', () => {
|
|
31
31
|
const mockProjectConfig = {
|
|
32
32
|
name: 'test-project',
|
|
33
33
|
srcDir: 'src',
|
|
34
|
-
platformVersion: '
|
|
34
|
+
platformVersion: '2025.2',
|
|
35
35
|
};
|
|
36
36
|
const mockArgs = {
|
|
37
37
|
name: 'test-component',
|
|
@@ -66,13 +66,13 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
66
66
|
},
|
|
67
67
|
};
|
|
68
68
|
beforeEach(() => {
|
|
69
|
-
|
|
69
|
+
mockedCreateV2App.mockResolvedValue({
|
|
70
70
|
authType: 'oauth',
|
|
71
71
|
distribution: 'private',
|
|
72
72
|
});
|
|
73
73
|
mockedTrackCommandUsage.mockResolvedValue();
|
|
74
74
|
});
|
|
75
|
-
describe('
|
|
75
|
+
describe('v2AddComponent()', () => {
|
|
76
76
|
it('successfully adds a component when app already exists', async () => {
|
|
77
77
|
const mockAppMeta = {
|
|
78
78
|
config: {
|
|
@@ -86,17 +86,17 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
86
86
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
87
87
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
|
|
88
88
|
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
89
|
-
|
|
89
|
+
mockedProjectAddPromptV2.mockResolvedValue(mockPromptResponse);
|
|
90
90
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
91
|
-
await
|
|
92
|
-
expect(mockedGetConfigForPlatformVersion).toHaveBeenCalledWith('
|
|
91
|
+
await v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
92
|
+
expect(mockedGetConfigForPlatformVersion).toHaveBeenCalledWith('2025.2');
|
|
93
93
|
expect(mockedGetProjectMetadata).toHaveBeenCalledWith('/path/to/project/src');
|
|
94
|
-
expect(
|
|
94
|
+
expect(mockedProjectAddPromptV2).toHaveBeenCalled();
|
|
95
95
|
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
96
96
|
type: 'module',
|
|
97
97
|
}, mockAccountId);
|
|
98
98
|
expect(mockedCloneGithubRepo).toHaveBeenCalledWith(expect.any(String), projectDir, expect.objectContaining({
|
|
99
|
-
sourceDir: ['
|
|
99
|
+
sourceDir: ['2025.2/test-component'],
|
|
100
100
|
hideLogs: true,
|
|
101
101
|
branch: 'main',
|
|
102
102
|
}));
|
|
@@ -116,15 +116,15 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
116
116
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
117
117
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadataNoApps);
|
|
118
118
|
mockedConfirmPrompt.mockResolvedValue(true);
|
|
119
|
-
|
|
119
|
+
mockedProjectAddPromptV2.mockResolvedValue(mockPromptResponse);
|
|
120
120
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
121
|
-
await
|
|
122
|
-
expect(
|
|
121
|
+
await v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
122
|
+
expect(mockedCreateV2App).toHaveBeenCalled();
|
|
123
123
|
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
124
124
|
type: 'module',
|
|
125
125
|
}, mockAccountId);
|
|
126
126
|
expect(mockedCloneGithubRepo).toHaveBeenCalledWith(expect.any(String), projectDir, expect.objectContaining({
|
|
127
|
-
sourceDir: ['
|
|
127
|
+
sourceDir: ['2025.2/test-component', '2025.2/app-template'],
|
|
128
128
|
}));
|
|
129
129
|
});
|
|
130
130
|
it('should not call clone', async () => {
|
|
@@ -145,10 +145,10 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
145
145
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
146
146
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadataNoApps);
|
|
147
147
|
mockedConfirmPrompt.mockResolvedValue(true);
|
|
148
|
-
|
|
148
|
+
mockedProjectAddPromptV2.mockResolvedValue(mockPromptResponse);
|
|
149
149
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
150
|
-
await
|
|
151
|
-
expect(
|
|
150
|
+
await v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
151
|
+
expect(mockedCreateV2App).not.toHaveBeenCalled();
|
|
152
152
|
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
153
153
|
type: '',
|
|
154
154
|
}, mockAccountId);
|
|
@@ -164,7 +164,7 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
164
164
|
};
|
|
165
165
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
166
166
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadataMaxApps);
|
|
167
|
-
await expect(
|
|
167
|
+
await expect(v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId)).rejects.toThrow('This project currently has the maximum number of apps: 1');
|
|
168
168
|
});
|
|
169
169
|
it('throws an error when components list is empty', async () => {
|
|
170
170
|
const mockEmptyConfig = {
|
|
@@ -172,7 +172,7 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
172
172
|
parentComponents: [],
|
|
173
173
|
};
|
|
174
174
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockEmptyConfig);
|
|
175
|
-
await expect(
|
|
175
|
+
await expect(v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId)).rejects.toThrow(commands.project.add.error.failedToFetchComponentList);
|
|
176
176
|
});
|
|
177
177
|
it('throws an error when app meta file cannot be parsed', async () => {
|
|
178
178
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
@@ -180,7 +180,7 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
180
180
|
mockedFs.readFileSync.mockImplementation(() => {
|
|
181
181
|
throw new Error('File read error');
|
|
182
182
|
});
|
|
183
|
-
await expect(
|
|
183
|
+
await expect(v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId)).rejects.toThrow('Unable to parse app file');
|
|
184
184
|
});
|
|
185
185
|
it('throws an error when cloning fails', async () => {
|
|
186
186
|
const mockAppMeta = {
|
|
@@ -195,9 +195,9 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
195
195
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
196
196
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
|
|
197
197
|
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
198
|
-
|
|
198
|
+
mockedProjectAddPromptV2.mockResolvedValue(mockPromptResponse);
|
|
199
199
|
mockedCloneGithubRepo.mockRejectedValue(new Error('Clone failed'));
|
|
200
|
-
await expect(
|
|
200
|
+
await expect(v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId)).rejects.toThrow(commands.project.add.error.failedToDownloadComponent);
|
|
201
201
|
});
|
|
202
202
|
it('should track usage with multiple component types', async () => {
|
|
203
203
|
const mockAppMeta = {
|
|
@@ -219,9 +219,9 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
219
219
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
220
220
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
|
|
221
221
|
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
222
|
-
|
|
222
|
+
mockedProjectAddPromptV2.mockResolvedValue(mockPromptResponse);
|
|
223
223
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
224
|
-
await
|
|
224
|
+
await v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
225
225
|
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
226
226
|
type: 'module,card',
|
|
227
227
|
}, mockAccountId);
|
|
@@ -243,8 +243,8 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
243
243
|
};
|
|
244
244
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
245
245
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadataNoApps);
|
|
246
|
-
|
|
247
|
-
await
|
|
246
|
+
mockedProjectAddPromptV2.mockResolvedValue(mockPromptResponse);
|
|
247
|
+
await v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
248
248
|
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
249
249
|
type: '',
|
|
250
250
|
}, mockAccountId);
|
|
@@ -270,9 +270,9 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
270
270
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
271
271
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
|
|
272
272
|
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
273
|
-
|
|
273
|
+
mockedProjectAddPromptV2.mockResolvedValue(mockPromptResponse);
|
|
274
274
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
275
|
-
await
|
|
275
|
+
await v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
276
276
|
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
277
277
|
type: 'workflow-action-tool',
|
|
278
278
|
}, mockAccountId);
|
|
@@ -308,9 +308,9 @@ describe('lib/projects/add/v3AddComponent', () => {
|
|
|
308
308
|
mockedGetConfigForPlatformVersion.mockResolvedValue(mockConfig);
|
|
309
309
|
mockedGetProjectMetadata.mockResolvedValue(mockProjectMetadata);
|
|
310
310
|
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockAppMeta));
|
|
311
|
-
|
|
311
|
+
mockedProjectAddPromptV2.mockResolvedValue(mockPromptResponse);
|
|
312
312
|
mockedCloneGithubRepo.mockResolvedValue(true);
|
|
313
|
-
await
|
|
313
|
+
await v2AddComponent(mockArgs, projectDir, mockProjectConfig, mockAccountId);
|
|
314
314
|
expect(mockedTrackCommandUsage).toHaveBeenCalledWith('project-add', {
|
|
315
315
|
type: 'workflow-action-tool,module',
|
|
316
316
|
}, mockAccountId);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { commands, lib } from '../../../lang/en.js';
|
|
2
2
|
import { getConfigForPlatformVersion } from '../create/legacy.js';
|
|
3
|
-
import { calculateComponentTemplateChoices,
|
|
3
|
+
import { calculateComponentTemplateChoices, createV2App, } from '../create/v2.js';
|
|
4
4
|
import { PROJECT_WITH_APP } from '../../constants.js';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import fs from 'fs';
|
|
7
|
-
import {
|
|
7
|
+
import { projectAddPromptV2 } from '../../prompts/projectAddPrompt.js';
|
|
8
8
|
import { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, DEFAULT_PROJECT_TEMPLATE_BRANCH, } from '../../constants.js';
|
|
9
9
|
import { updateHsMetaFilesWithAutoGeneratedFields, handleComponentCollision, } from '../components.js';
|
|
10
10
|
import { getProjectMetadata, } from '@hubspot/project-parsing-lib/src/lib/project.js';
|
|
@@ -13,7 +13,7 @@ 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
|
|
16
|
+
export async function v2AddComponent(args, projectDir, projectConfig, accountId) {
|
|
17
17
|
uiLogger.log(commands.project.add.creatingComponent(projectConfig.name));
|
|
18
18
|
const config = await getConfigForPlatformVersion(projectConfig.platformVersion);
|
|
19
19
|
const { components, parentComponents } = config;
|
|
@@ -27,7 +27,7 @@ export async function v3AddComponent(args, projectDir, projectConfig, accountId)
|
|
|
27
27
|
const appsMetadata = currentProjectMetadata.components[AppKey];
|
|
28
28
|
const shouldCreateApp = appsMetadata.count === 0;
|
|
29
29
|
if (shouldCreateApp) {
|
|
30
|
-
const { authType, distribution } = await
|
|
30
|
+
const { authType, distribution } = await createV2App(args.auth, args.distribution);
|
|
31
31
|
derivedDistribution = distribution;
|
|
32
32
|
derivedAuthType = authType;
|
|
33
33
|
}
|
|
@@ -47,7 +47,7 @@ export async function v3AddComponent(args, projectDir, projectConfig, accountId)
|
|
|
47
47
|
derivedAuthType = apps[0].config?.auth?.type;
|
|
48
48
|
}
|
|
49
49
|
const componentTemplateChoices = await calculateComponentTemplateChoices(components, derivedAuthType, derivedDistribution, args.derivedAccountId, currentProjectMetadata);
|
|
50
|
-
const projectAddPromptResponse = await
|
|
50
|
+
const projectAddPromptResponse = await projectAddPromptV2(componentTemplateChoices, args.features);
|
|
51
51
|
const componentTypes = projectAddPromptResponse.componentTemplate?.map(componentTemplate => componentTemplate.cliSelector || componentTemplate.type);
|
|
52
52
|
await trackCommandUsage('project-add', {
|
|
53
53
|
type: componentTypes?.join(','),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { calculateComponentTemplateChoices } from '../
|
|
1
|
+
import { calculateComponentTemplateChoices } from '../v2.js';
|
|
2
2
|
import { hasFeature } from '../../../hasFeature.js';
|
|
3
3
|
vi.mock('../../ui/logger.js');
|
|
4
4
|
vi.mock('@hubspot/local-dev-lib/api/github');
|
|
5
5
|
vi.mock('../../../hasFeature.js');
|
|
6
6
|
const mockHasFeature = vi.mocked(hasFeature);
|
|
7
|
-
describe('lib/projects/create/
|
|
7
|
+
describe('lib/projects/create/v2', () => {
|
|
8
8
|
beforeEach(() => {
|
|
9
9
|
mockHasFeature.mockResolvedValue(true);
|
|
10
10
|
});
|
|
@@ -2,7 +2,7 @@ import { selectProjectTemplatePrompt, } from '../../prompts/selectProjectTemplat
|
|
|
2
2
|
import { projectNameAndDestPrompt } from '../../prompts/projectNameAndDestPrompt.js';
|
|
3
3
|
import { DEFAULT_PROJECT_TEMPLATE_BRANCH, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, EMPTY_PROJECT, } from '../../constants.js';
|
|
4
4
|
import { isV2Project } from '../platformVersion.js';
|
|
5
|
-
import {
|
|
5
|
+
import { v2ComponentFlow } from './v2.js';
|
|
6
6
|
import { getProjectTemplateListFromRepo } from './legacy.js';
|
|
7
7
|
import { uiLogger } from '../../ui/logger.js';
|
|
8
8
|
import { commands } from '../../../lang/en.js';
|
|
@@ -12,7 +12,7 @@ export async function handleProjectCreationFlow(args) {
|
|
|
12
12
|
const repo = templateSource || HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH;
|
|
13
13
|
const projectNameAndDestPromptResponse = await projectNameAndDestPrompt(args);
|
|
14
14
|
if (isV2Project(platformVersion)) {
|
|
15
|
-
const { componentTemplateChoices, authType, distribution, repoConfig, projectContents, } = await
|
|
15
|
+
const { componentTemplateChoices, authType, distribution, repoConfig, projectContents, } = await v2ComponentFlow(platformVersion, projectBase, providedAuth, providedDistribution, args.derivedAccountId);
|
|
16
16
|
const selectProjectTemplatePromptResponse = await selectProjectTemplatePrompt(args, undefined, projectContents !== EMPTY_PROJECT ? componentTemplateChoices : undefined);
|
|
17
17
|
return {
|
|
18
18
|
authType,
|
|
@@ -2,19 +2,19 @@ import { Separator } from '@inquirer/prompts';
|
|
|
2
2
|
import { ComponentTemplate, ComponentTemplateChoice, ProjectTemplateRepoConfig } from '../../../types/Projects.js';
|
|
3
3
|
import { ProjectMetadata } from '@hubspot/project-parsing-lib/src/lib/project.js';
|
|
4
4
|
import { SelectProjectTemplatePromptResponse } from '../../prompts/selectProjectTemplatePrompt.js';
|
|
5
|
-
export declare function
|
|
5
|
+
export declare function createV2App(providedAuth: string | undefined, providedDistribution: string | undefined): Promise<{
|
|
6
6
|
authType: string;
|
|
7
7
|
distribution: string;
|
|
8
8
|
}>;
|
|
9
9
|
export declare function calculateComponentTemplateChoices(components: ComponentTemplate[], authType: string | undefined, distribution: string | undefined, accountId: number, projectMetadata?: ProjectMetadata): Promise<(ComponentTemplateChoice | Separator)[]>;
|
|
10
|
-
type
|
|
10
|
+
type V2ComponentInfo = {
|
|
11
11
|
authType?: string;
|
|
12
12
|
distribution?: string;
|
|
13
13
|
repoConfig?: ProjectTemplateRepoConfig;
|
|
14
14
|
projectContents?: string;
|
|
15
15
|
componentTemplateChoices?: (ComponentTemplateChoice | Separator)[];
|
|
16
16
|
};
|
|
17
|
-
export declare function
|
|
17
|
+
export declare function v2ComponentFlow(platformVersion: string, projectBase: string | undefined, providedAuth: string | undefined, providedDistribution: string | undefined, accountId: number): Promise<V2ComponentInfo>;
|
|
18
18
|
export declare function generateComponentPaths({ selectProjectTemplatePromptResponse, platformVersion, repoConfig, projectContents, authType, distribution, }: {
|
|
19
19
|
selectProjectTemplatePromptResponse: SelectProjectTemplatePromptResponse;
|
|
20
20
|
platformVersion: string;
|
|
@@ -10,7 +10,7 @@ import { logError } from '../../errorHandlers/index.js';
|
|
|
10
10
|
import { EXIT_CODES } from '../../enums/exitCodes.js';
|
|
11
11
|
import { hasFeature } from '../../hasFeature.js';
|
|
12
12
|
import { AppEventsKey, PagesKey, } from '@hubspot/project-parsing-lib/src/lib/constants.js';
|
|
13
|
-
export async function
|
|
13
|
+
export async function createV2App(providedAuth, providedDistribution) {
|
|
14
14
|
let authType;
|
|
15
15
|
if (providedAuth &&
|
|
16
16
|
providedDistribution === marketplaceDistribution &&
|
|
@@ -112,7 +112,7 @@ export async function calculateComponentTemplateChoices(components, authType, di
|
|
|
112
112
|
]
|
|
113
113
|
: [...enabledComponents];
|
|
114
114
|
}
|
|
115
|
-
export async function
|
|
115
|
+
export async function v2ComponentFlow(platformVersion, projectBase, providedAuth, providedDistribution, accountId) {
|
|
116
116
|
let repoConfig = undefined;
|
|
117
117
|
let authType;
|
|
118
118
|
let distribution;
|
|
@@ -134,7 +134,7 @@ export async function v3ComponentFlow(platformVersion, projectBase, providedAuth
|
|
|
134
134
|
],
|
|
135
135
|
}));
|
|
136
136
|
if (projectContentsChoice === PROJECT_WITH_APP) {
|
|
137
|
-
const { authType: selectedAuthType, distribution: selectedDistribution } = await
|
|
137
|
+
const { authType: selectedAuthType, distribution: selectedDistribution } = await createV2App(providedAuth, providedDistribution);
|
|
138
138
|
authType = selectedAuthType;
|
|
139
139
|
distribution = selectedDistribution;
|
|
140
140
|
}
|
package/lib/projects/deploy.d.ts
CHANGED
|
@@ -10,4 +10,4 @@ export declare function logDeployErrors(errorData: {
|
|
|
10
10
|
};
|
|
11
11
|
}>;
|
|
12
12
|
}): void;
|
|
13
|
-
export declare function handleProjectDeploy(targetAccountId: number, projectName: string, buildId: number,
|
|
13
|
+
export declare function handleProjectDeploy(targetAccountId: number, projectName: string, buildId: number, isV2Project: boolean, force: boolean): Promise<Deploy | undefined>;
|
package/lib/projects/deploy.js
CHANGED
|
@@ -47,8 +47,8 @@ function handleBlockedDeploy(deployResp) {
|
|
|
47
47
|
uiLogger.log('');
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
-
export async function handleProjectDeploy(targetAccountId, projectName, buildId,
|
|
51
|
-
const { data: deployResp } = await deployProject(targetAccountId, projectName, buildId,
|
|
50
|
+
export async function handleProjectDeploy(targetAccountId, projectName, buildId, isV2Project, force) {
|
|
51
|
+
const { data: deployResp } = await deployProject(targetAccountId, projectName, buildId, isV2Project, force);
|
|
52
52
|
if (!deployResp || deployResp.buildResultType !== 'DEPLOY_QUEUED') {
|
|
53
53
|
if (deployResp?.buildResultType === 'DEPLOY_BLOCKED') {
|
|
54
54
|
handleBlockedDeploy(deployResp);
|