@hubspot/cli 7.10.0 → 7.10.1-experimental.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +5 -4
- package/commands/__tests__/getStarted.test.js +10 -0
- package/commands/__tests__/project.test.js +3 -0
- package/commands/account/__tests__/rename.test.js +10 -3
- package/commands/account/auth.js +10 -14
- package/commands/account/clean.js +11 -19
- package/commands/account/createOverride.js +15 -11
- package/commands/account/info.js +8 -5
- package/commands/account/list.js +15 -19
- package/commands/account/remove.js +23 -22
- package/commands/account/removeOverride.js +6 -6
- package/commands/account/rename.js +2 -2
- package/commands/account/use.js +19 -8
- package/commands/app/__tests__/migrate.test.js +8 -4
- package/commands/app/migrate.js +2 -2
- package/commands/auth.js +18 -14
- package/commands/config/migrate.js +5 -5
- package/commands/customObject/createSchema.js +2 -3
- package/commands/customObject/updateSchema.js +2 -3
- package/commands/getStarted.js +2 -3
- package/commands/hubdb/__tests__/list.test.js +1 -0
- package/commands/hubdb/list.js +2 -2
- package/commands/init.js +36 -32
- package/commands/project/__tests__/deploy.test.js +10 -5
- package/commands/project/__tests__/devUnifiedFlow.test.js +6 -4
- package/commands/project/__tests__/lint.test.js +709 -0
- package/commands/project/__tests__/logs.test.js +4 -0
- package/commands/project/__tests__/validate.test.js +286 -28
- package/commands/project/cloneApp.js +2 -2
- package/commands/project/deploy.js +16 -8
- package/commands/project/dev/deprecatedFlow.js +4 -5
- package/commands/project/dev/index.js +19 -7
- package/commands/project/dev/unifiedFlow.js +4 -5
- package/commands/project/lint.d.ts +6 -0
- package/commands/project/lint.js +178 -0
- package/commands/project/logs.js +2 -3
- package/commands/project/migrate.js +4 -13
- package/commands/project/profile/add.js +6 -7
- package/commands/project/profile/delete.js +2 -2
- package/commands/project/upload.js +10 -4
- package/commands/project/validate.js +73 -13
- package/commands/project.js +2 -0
- package/commands/sandbox/__tests__/create.test.js +14 -5
- package/commands/sandbox/create.js +4 -5
- package/commands/sandbox/delete.js +23 -20
- package/commands/testAccount/create.js +2 -2
- package/commands/testAccount/delete.js +9 -8
- package/lang/en.d.ts +48 -11
- package/lang/en.js +58 -15
- package/lib/__tests__/buildAccount.test.js +22 -30
- package/lib/__tests__/commonOpts.test.js +9 -13
- package/lib/__tests__/developerTestAccounts.test.js +29 -17
- package/lib/__tests__/importData.test.js +20 -10
- package/lib/__tests__/oauth.test.js +19 -8
- package/lib/__tests__/projectProfiles.test.js +273 -32
- package/lib/__tests__/sandboxSync.test.js +33 -11
- package/lib/__tests__/sandboxes.test.js +30 -19
- package/lib/__tests__/usageTracking.test.js +10 -10
- package/lib/__tests__/validation.test.js +32 -32
- package/lib/accountTypes.d.ts +9 -9
- package/lib/accountTypes.js +2 -4
- package/lib/app/__tests__/migrate.test.js +15 -0
- package/lib/app/__tests__/migrate_legacy.test.js +9 -0
- package/lib/app/migrate_legacy.d.ts +2 -2
- package/lib/buildAccount.d.ts +4 -4
- package/lib/buildAccount.js +7 -14
- package/lib/commonOpts.js +3 -3
- package/lib/configMigrate.d.ts +2 -2
- package/lib/configMigrate.js +42 -18
- package/lib/configOptions.js +3 -2
- package/lib/developerTestAccounts.d.ts +3 -3
- package/lib/developerTestAccounts.js +4 -7
- package/lib/doctor/DiagnosticInfoBuilder.d.ts +1 -1
- package/lib/doctor/DiagnosticInfoBuilder.js +9 -6
- package/lib/doctor/Doctor.js +4 -3
- package/lib/doctor/__tests__/Diagnosis.test.js +4 -3
- package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.js +17 -9
- package/lib/doctor/__tests__/Doctor.test.js +14 -0
- package/lib/importData.js +8 -7
- package/lib/links.js +5 -5
- package/lib/middleware/{__test__ → __tests__}/commandTargetingUtils.test.js +3 -3
- package/lib/middleware/{__test__ → __tests__}/configMiddleware.test.js +23 -22
- package/lib/middleware/{__test__ → __tests__}/gitMiddleware.test.js +9 -7
- package/lib/middleware/autoUpdateMiddleware.js +34 -23
- package/lib/middleware/commandTargetingUtils.js +3 -2
- package/lib/middleware/configMiddleware.d.ts +6 -1
- package/lib/middleware/configMiddleware.js +36 -15
- package/lib/middleware/fireAlarmMiddleware.js +4 -15
- package/lib/middleware/gitMiddleware.js +8 -4
- package/lib/oauth.d.ts +2 -2
- package/lib/oauth.js +8 -10
- package/lib/projectProfiles.d.ts +4 -3
- package/lib/projectProfiles.js +78 -32
- package/lib/projects/__tests__/AppDevModeInterface.test.js +17 -6
- package/lib/projects/__tests__/DevServerManager.test.js +1 -0
- package/lib/projects/__tests__/LocalDevProcess.test.js +1 -0
- package/lib/projects/__tests__/deploy.test.js +1 -0
- package/lib/projects/__tests__/uieLinting.test.js +640 -0
- package/lib/projects/create/__tests__/v2.test.js +11 -0
- package/lib/projects/localDev/AppDevModeInterface.js +2 -2
- package/lib/projects/localDev/DevServerManager_DEPRECATED.js +2 -2
- package/lib/projects/localDev/LocalDevLogger.js +4 -4
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +3 -3
- package/lib/projects/localDev/helpers/account.d.ts +10 -10
- package/lib/projects/localDev/helpers/account.js +6 -11
- package/lib/projects/uieLinting.d.ts +33 -0
- package/lib/projects/uieLinting.js +222 -0
- package/lib/projects/urls.js +5 -6
- package/lib/prompts/__tests__/downloadProjectPrompt.test.js +7 -5
- package/lib/prompts/accountNamePrompt.js +3 -3
- package/lib/prompts/accountsPrompt.d.ts +1 -1
- package/lib/prompts/accountsPrompt.js +6 -7
- package/lib/prompts/confirmImportDataPrompt.js +2 -2
- package/lib/prompts/downloadProjectPrompt.d.ts +1 -0
- package/lib/prompts/downloadProjectPrompt.js +5 -2
- package/lib/prompts/importDataTestAccountSelectPrompt.js +4 -5
- package/lib/prompts/personalAccessKeyPrompt.js +2 -2
- package/lib/prompts/projectDevTargetAccountPrompt.d.ts +3 -3
- package/lib/prompts/projectDevTargetAccountPrompt.js +5 -7
- package/lib/prompts/sandboxesPrompt.js +7 -8
- package/lib/prompts/setAsDefaultAccountPrompt.js +7 -6
- package/lib/sandboxSync.d.ts +2 -2
- package/lib/sandboxSync.js +3 -9
- package/lib/sandboxes.d.ts +4 -4
- package/lib/sandboxes.js +6 -11
- package/lib/serverlessLogs.js +2 -2
- package/lib/theme/__tests__/migrate.test.js +15 -0
- package/lib/ui/index.js +6 -3
- package/lib/usageTracking.js +15 -8
- package/lib/validation.js +13 -11
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +4 -2
- package/mcp-server/tools/cms/HsCreateModuleTool.js +4 -2
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +4 -2
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +4 -2
- package/mcp-server/tools/cms/HsListFunctionsTool.js +3 -1
- package/mcp-server/tools/cms/HsListTool.js +3 -1
- package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +1 -0
- package/mcp-server/tools/index.js +4 -0
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +4 -2
- package/mcp-server/tools/project/CreateProjectTool.js +4 -2
- package/mcp-server/tools/project/CreateTestAccountTool.js +17 -7
- package/mcp-server/tools/project/DeployProjectTool.js +3 -1
- package/mcp-server/tools/project/DocFetchTool.js +6 -4
- package/mcp-server/tools/project/DocsSearchTool.d.ts +1 -1
- package/mcp-server/tools/project/DocsSearchTool.js +10 -8
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +1 -1
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +9 -7
- package/mcp-server/tools/project/GetApplicationInfoTool.js +8 -6
- package/mcp-server/tools/project/GetBuildLogsTool.d.ts +26 -0
- package/mcp-server/tools/project/GetBuildLogsTool.js +125 -0
- package/mcp-server/tools/project/GetBuildStatusTool.d.ts +26 -0
- package/mcp-server/tools/project/GetBuildStatusTool.js +166 -0
- package/mcp-server/tools/project/GetConfigValuesTool.d.ts +1 -1
- package/mcp-server/tools/project/GetConfigValuesTool.js +9 -7
- package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +1 -1
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +5 -3
- package/mcp-server/tools/project/UploadProjectTools.js +3 -1
- package/mcp-server/tools/project/ValidateProjectTool.js +4 -2
- package/mcp-server/tools/project/__tests__/CreateTestAccountTool.test.js +12 -2
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +5 -1
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +23 -11
- package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +7 -5
- package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +7 -5
- package/mcp-server/tools/project/__tests__/GetBuildLogsTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/GetBuildLogsTool.test.js +305 -0
- package/mcp-server/tools/project/__tests__/GetBuildStatusTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/GetBuildStatusTool.test.js +240 -0
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +8 -6
- package/mcp-server/utils/__tests__/content.test.js +21 -20
- package/mcp-server/utils/__tests__/feedbackTracking.test.js +34 -28
- package/mcp-server/utils/config.d.ts +1 -0
- package/mcp-server/utils/config.js +10 -0
- package/mcp-server/utils/content.d.ts +1 -1
- package/mcp-server/utils/content.js +2 -2
- package/mcp-server/utils/feedbackTracking.d.ts +1 -1
- package/mcp-server/utils/feedbackTracking.js +3 -3
- package/mcp-server/utils/toolUsageTracking.js +4 -3
- package/package.json +9 -9
- package/ui/components/BoxWithTitle.d.ts +2 -1
- package/ui/components/BoxWithTitle.js +2 -2
- package/ui/components/StatusMessageBoxes.d.ts +5 -4
- package/ui/components/StatusMessageBoxes.js +8 -8
- package/lib/middleware/__test__/notificationsMiddleware.test.js +0 -8
- package/lib/middleware/notificationsMiddleware.d.ts +0 -1
- package/lib/middleware/notificationsMiddleware.js +0 -28
- package/lib/ui/boxen.d.ts +0 -5
- package/lib/ui/boxen.js +0 -26
- package/mcp-server/utils/__tests__/cliConfig.test.js +0 -110
- package/mcp-server/utils/cliConfig.d.ts +0 -1
- package/mcp-server/utils/cliConfig.js +0 -12
- /package/{lib/middleware/__test__/commandTargetingUtils.test.d.ts → commands/project/__tests__/lint.test.d.ts} +0 -0
- /package/lib/middleware/{__test__/configMiddleware.test.d.ts → __tests__/commandTargetingUtils.test.d.ts} +0 -0
- /package/lib/middleware/{__test__/gitMiddleware.test.d.ts → __tests__/configMiddleware.test.d.ts} +0 -0
- /package/lib/middleware/{__test__/notificationsMiddleware.test.d.ts → __tests__/gitMiddleware.test.d.ts} +0 -0
- /package/lib/middleware/{__test__ → __tests__}/requestMiddleware.test.d.ts +0 -0
- /package/lib/middleware/{__test__ → __tests__}/requestMiddleware.test.js +0 -0
- /package/lib/middleware/{__test__ → __tests__}/yargsChecksMiddleware.test.d.ts +0 -0
- /package/lib/middleware/{__test__ → __tests__}/yargsChecksMiddleware.test.js +0 -0
- /package/{mcp-server/utils/__tests__/cliConfig.test.d.ts → lib/projects/__tests__/uieLinting.test.d.ts} +0 -0
|
@@ -8,6 +8,8 @@ import * as ui from '../../../lib/ui/index.js';
|
|
|
8
8
|
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
9
9
|
import { logError } from '../../../lib/errorHandlers/index.js';
|
|
10
10
|
import projectLogsCommand from '../logs.js';
|
|
11
|
+
import * as config from '@hubspot/local-dev-lib/config';
|
|
12
|
+
import { ENVIRONMENTS } from '@hubspot/local-dev-lib/constants/environments';
|
|
11
13
|
vi.mock('../../ui/logger.js');
|
|
12
14
|
vi.mock('../../../lib/commonOpts');
|
|
13
15
|
vi.mock('../../../lib/usageTracking');
|
|
@@ -25,6 +27,7 @@ const projectLogsManagerGetFunctionNamesSpy = vi.spyOn(ProjectLogsManager, 'getF
|
|
|
25
27
|
const projectLogsManagerInitSpy = vi.spyOn(ProjectLogsManager, 'init');
|
|
26
28
|
const getTableHeaderSpy = vi.spyOn(table, 'getTableHeader');
|
|
27
29
|
const getTableContentsSpy = vi.spyOn(table, 'getTableContents');
|
|
30
|
+
const getConfigAccountEnvironmentSpy = vi.spyOn(config, 'getConfigAccountEnvironment');
|
|
28
31
|
const optionsSpy = vi
|
|
29
32
|
.spyOn(yargs, 'options')
|
|
30
33
|
.mockReturnValue(yargs);
|
|
@@ -34,6 +37,7 @@ const conflictsSpy = vi
|
|
|
34
37
|
const exampleSpy = vi
|
|
35
38
|
.spyOn(yargs, 'example')
|
|
36
39
|
.mockReturnValue(yargs);
|
|
40
|
+
getConfigAccountEnvironmentSpy.mockReturnValue(ENVIRONMENTS.PROD);
|
|
37
41
|
describe('commands/project/logs', () => {
|
|
38
42
|
beforeEach(() => {
|
|
39
43
|
// @ts-expect-error Doesn't match the actual signature because then the linter complains about unused variables
|
|
@@ -5,11 +5,14 @@ import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/
|
|
|
5
5
|
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
6
6
|
import { commands } from '../../../lang/en.js';
|
|
7
7
|
import { isV2Project } from '../../../lib/projects/platformVersion.js';
|
|
8
|
-
import {
|
|
8
|
+
import { validateProjectForProfile } from '../../../lib/projectProfiles.js';
|
|
9
9
|
import { trackCommandUsage } from '../../../lib/usageTracking.js';
|
|
10
|
-
import {
|
|
10
|
+
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
11
11
|
import { handleTranslate } from '../../../lib/projects/upload.js';
|
|
12
12
|
import projectValidateCommand from '../validate.js';
|
|
13
|
+
import { getAllHsProfiles } from '@hubspot/project-parsing-lib';
|
|
14
|
+
import SpinniesManager from '../../../lib/ui/SpinniesManager.js';
|
|
15
|
+
import { logError } from '../../../lib/errorHandlers/index.js';
|
|
13
16
|
// Mock dependencies
|
|
14
17
|
vi.mock('../../../lib/projects/upload.js');
|
|
15
18
|
vi.mock('../../../lib/projects/config.js');
|
|
@@ -19,15 +22,35 @@ vi.mock('../../../lib/projectProfiles.js');
|
|
|
19
22
|
vi.mock('../../../lib/errorHandlers/index.js');
|
|
20
23
|
vi.mock('@hubspot/local-dev-lib/config');
|
|
21
24
|
vi.mock('../../../lib/projects/platformVersion.js');
|
|
25
|
+
vi.mock('@hubspot/project-parsing-lib');
|
|
26
|
+
vi.mock('../../../lib/ui/SpinniesManager.js');
|
|
22
27
|
describe('commands/project/validate', () => {
|
|
23
28
|
const projectDir = '/test/project';
|
|
24
29
|
let exitSpy;
|
|
30
|
+
const mockProjectConfig = {
|
|
31
|
+
name: 'test-project',
|
|
32
|
+
srcDir: 'src',
|
|
33
|
+
platformVersion: '2025.2',
|
|
34
|
+
};
|
|
35
|
+
const mockAccountConfig = {
|
|
36
|
+
accountType: 'STANDARD',
|
|
37
|
+
accountId: 123,
|
|
38
|
+
env: 'prod',
|
|
39
|
+
};
|
|
25
40
|
beforeEach(() => {
|
|
26
41
|
// Mock process.exit to throw to stop execution
|
|
27
42
|
exitSpy = vi.spyOn(process, 'exit').mockImplementation(code => {
|
|
28
43
|
throw new Error(`Process exited with code ${code}`);
|
|
29
44
|
});
|
|
30
45
|
vi.clearAllMocks();
|
|
46
|
+
// Set up default mocks
|
|
47
|
+
vi.mocked(getConfigAccountById).mockReturnValue(mockAccountConfig);
|
|
48
|
+
vi.mocked(trackCommandUsage);
|
|
49
|
+
vi.mocked(SpinniesManager.init);
|
|
50
|
+
vi.mocked(SpinniesManager.add);
|
|
51
|
+
vi.mocked(SpinniesManager.succeed);
|
|
52
|
+
vi.mocked(SpinniesManager.fail);
|
|
53
|
+
vi.mocked(validateProjectForProfile).mockResolvedValue([]);
|
|
31
54
|
});
|
|
32
55
|
afterEach(() => {
|
|
33
56
|
exitSpy.mockRestore();
|
|
@@ -65,34 +88,269 @@ describe('commands/project/validate', () => {
|
|
|
65
88
|
})).rejects.toThrow('Process exited with code 1');
|
|
66
89
|
expect(uiLogger.error).toHaveBeenCalledWith(commands.project.validate.mustBeRanWithinAProject);
|
|
67
90
|
});
|
|
91
|
+
it('should exit with error for non-V2 projects', async () => {
|
|
92
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
93
|
+
projectConfig: {
|
|
94
|
+
name: 'test',
|
|
95
|
+
srcDir: 'src',
|
|
96
|
+
platformVersion: '2024.1',
|
|
97
|
+
},
|
|
98
|
+
projectDir,
|
|
99
|
+
});
|
|
100
|
+
vi.mocked(isV2Project).mockReturnValue(false);
|
|
101
|
+
await expect(
|
|
102
|
+
// @ts-expect-error partial mock
|
|
103
|
+
projectValidateCommand.handler({
|
|
104
|
+
derivedAccountId: 123,
|
|
105
|
+
d: false,
|
|
106
|
+
debug: false,
|
|
107
|
+
})).rejects.toThrow('Process exited with code 1');
|
|
108
|
+
expect(uiLogger.error).toHaveBeenCalledWith(commands.project.validate.badVersion);
|
|
109
|
+
});
|
|
110
|
+
it('should exit with error when validateProjectConfig throws', async () => {
|
|
111
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
112
|
+
projectConfig: mockProjectConfig,
|
|
113
|
+
projectDir,
|
|
114
|
+
});
|
|
115
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
116
|
+
const error = new Error('Invalid project config');
|
|
117
|
+
vi.mocked(validateProjectConfig).mockImplementation(() => {
|
|
118
|
+
throw error;
|
|
119
|
+
});
|
|
120
|
+
await expect(
|
|
121
|
+
// @ts-expect-error partial mock
|
|
122
|
+
projectValidateCommand.handler({
|
|
123
|
+
derivedAccountId: 123,
|
|
124
|
+
d: false,
|
|
125
|
+
debug: false,
|
|
126
|
+
})).rejects.toThrow('Process exited with code 1');
|
|
127
|
+
expect(logError).toHaveBeenCalledWith(error);
|
|
128
|
+
});
|
|
68
129
|
});
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
130
|
+
describe('profile validation', () => {
|
|
131
|
+
describe('when a specific profile is provided', () => {
|
|
132
|
+
it('should validate only the specified profile', async () => {
|
|
133
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
134
|
+
projectConfig: mockProjectConfig,
|
|
135
|
+
projectDir,
|
|
136
|
+
});
|
|
137
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
138
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
139
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue(['dev', 'prod', 'qa']);
|
|
140
|
+
vi.mocked(validateProjectForProfile).mockResolvedValue([]);
|
|
141
|
+
vi.mocked(validateSourceDirectory).mockResolvedValue(undefined);
|
|
142
|
+
await expect(projectValidateCommand.handler({
|
|
143
|
+
derivedAccountId: 123,
|
|
144
|
+
profile: 'dev',
|
|
145
|
+
d: false,
|
|
146
|
+
debug: false,
|
|
147
|
+
})).rejects.toThrow('Process exited with code 0');
|
|
148
|
+
// Should call validateProjectForProfile for the specified profile
|
|
149
|
+
expect(validateProjectForProfile).toHaveBeenCalledWith(mockProjectConfig, projectDir, 'dev', 123);
|
|
150
|
+
expect(uiLogger.success).toHaveBeenCalledWith(commands.project.validate.success(mockProjectConfig.name));
|
|
151
|
+
});
|
|
152
|
+
it('should handle profile validation failure', async () => {
|
|
153
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
154
|
+
projectConfig: mockProjectConfig,
|
|
155
|
+
projectDir,
|
|
156
|
+
});
|
|
157
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
158
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
159
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue(['dev', 'prod']);
|
|
160
|
+
const error = new Error('Profile not found');
|
|
161
|
+
vi.mocked(validateProjectForProfile).mockResolvedValue([error.message]);
|
|
162
|
+
await expect(projectValidateCommand.handler({
|
|
163
|
+
derivedAccountId: 123,
|
|
164
|
+
profile: 'dev',
|
|
165
|
+
d: false,
|
|
166
|
+
debug: false,
|
|
167
|
+
})).rejects.toThrow('Process exited with code 1');
|
|
168
|
+
// The error message is logged as a string, not the Error object
|
|
169
|
+
expect(uiLogger.error).toHaveBeenCalledWith(error.message);
|
|
170
|
+
});
|
|
171
|
+
it('should handle translate failure for a profile', async () => {
|
|
172
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
173
|
+
projectConfig: mockProjectConfig,
|
|
174
|
+
projectDir,
|
|
175
|
+
});
|
|
176
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
177
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
178
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue(['dev', 'prod']);
|
|
179
|
+
const error = new Error('Translation failed');
|
|
180
|
+
vi.mocked(validateProjectForProfile).mockResolvedValue([
|
|
181
|
+
commands.project.validate.failure(mockProjectConfig.name),
|
|
182
|
+
error,
|
|
183
|
+
]);
|
|
184
|
+
await expect(projectValidateCommand.handler({
|
|
185
|
+
derivedAccountId: 123,
|
|
186
|
+
profile: 'dev',
|
|
187
|
+
d: false,
|
|
188
|
+
debug: false,
|
|
189
|
+
})).rejects.toThrow('Process exited with code 1');
|
|
190
|
+
// The error object is logged via logError
|
|
191
|
+
expect(logError).toHaveBeenCalledWith(error);
|
|
192
|
+
});
|
|
78
193
|
});
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
194
|
+
describe('when no profile is provided and project has profiles', () => {
|
|
195
|
+
it('should validate all profiles', async () => {
|
|
196
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
197
|
+
projectConfig: mockProjectConfig,
|
|
198
|
+
projectDir,
|
|
199
|
+
});
|
|
200
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
201
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
202
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue(['dev', 'prod', 'qa']);
|
|
203
|
+
vi.mocked(validateProjectForProfile).mockResolvedValue([]);
|
|
204
|
+
vi.mocked(validateSourceDirectory).mockResolvedValue(undefined);
|
|
205
|
+
await expect(projectValidateCommand.handler({
|
|
206
|
+
derivedAccountId: 123,
|
|
207
|
+
d: false,
|
|
208
|
+
debug: false,
|
|
209
|
+
})).rejects.toThrow('Process exited with code 0');
|
|
210
|
+
// Should validate all three profiles
|
|
211
|
+
expect(validateProjectForProfile).toHaveBeenCalledTimes(3);
|
|
212
|
+
expect(validateProjectForProfile).toHaveBeenCalledWith(mockProjectConfig, projectDir, 'dev', 123, true);
|
|
213
|
+
expect(validateProjectForProfile).toHaveBeenCalledWith(mockProjectConfig, projectDir, 'prod', 123, true);
|
|
214
|
+
expect(validateProjectForProfile).toHaveBeenCalledWith(mockProjectConfig, projectDir, 'qa', 123, true);
|
|
215
|
+
// Should show success for all profiles
|
|
216
|
+
expect(SpinniesManager.succeed).toHaveBeenCalledWith('validatingAllProfiles', expect.any(Object));
|
|
217
|
+
expect(uiLogger.success).toHaveBeenCalledWith(commands.project.validate.success(mockProjectConfig.name));
|
|
218
|
+
});
|
|
219
|
+
it('should handle failure when validating multiple profiles', async () => {
|
|
220
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
221
|
+
projectConfig: mockProjectConfig,
|
|
222
|
+
projectDir,
|
|
223
|
+
});
|
|
224
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
225
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
226
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue(['dev', 'prod']);
|
|
227
|
+
vi.mocked(validateProjectForProfile)
|
|
228
|
+
.mockResolvedValueOnce([]) // dev succeeds
|
|
229
|
+
.mockResolvedValueOnce(['Profile not found']); // prod fails
|
|
230
|
+
await expect(projectValidateCommand.handler({
|
|
231
|
+
derivedAccountId: 123,
|
|
232
|
+
d: false,
|
|
233
|
+
debug: false,
|
|
234
|
+
})).rejects.toThrow('Process exited with code 1');
|
|
235
|
+
expect(SpinniesManager.fail).toHaveBeenCalledWith('validatingAllProfiles', expect.any(Object));
|
|
236
|
+
});
|
|
237
|
+
it('should continue validating remaining profiles after one fails', async () => {
|
|
238
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
239
|
+
projectConfig: mockProjectConfig,
|
|
240
|
+
projectDir,
|
|
241
|
+
});
|
|
242
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
243
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
244
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue(['dev', 'prod', 'qa']);
|
|
245
|
+
vi.mocked(validateProjectForProfile)
|
|
246
|
+
.mockResolvedValueOnce([]) // dev succeeds
|
|
247
|
+
.mockResolvedValueOnce(['Profile not found']) // prod fails
|
|
248
|
+
.mockResolvedValueOnce([]); // qa succeeds
|
|
249
|
+
vi.mocked(validateSourceDirectory).mockResolvedValue(undefined);
|
|
250
|
+
await expect(projectValidateCommand.handler({
|
|
251
|
+
derivedAccountId: 123,
|
|
252
|
+
d: false,
|
|
253
|
+
debug: false,
|
|
254
|
+
})).rejects.toThrow('Process exited with code 1');
|
|
255
|
+
// All three profiles should be attempted
|
|
256
|
+
expect(validateProjectForProfile).toHaveBeenCalledTimes(3);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
describe('when no profile is provided and project has no profiles', () => {
|
|
260
|
+
it('should validate without a profile', async () => {
|
|
261
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
262
|
+
projectConfig: mockProjectConfig,
|
|
263
|
+
projectDir,
|
|
264
|
+
});
|
|
265
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
266
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
267
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue([]);
|
|
268
|
+
vi.mocked(handleTranslate).mockResolvedValue(undefined);
|
|
269
|
+
vi.mocked(validateSourceDirectory).mockResolvedValue(undefined);
|
|
270
|
+
await expect(projectValidateCommand.handler({
|
|
271
|
+
derivedAccountId: 123,
|
|
272
|
+
d: false,
|
|
273
|
+
debug: false,
|
|
274
|
+
})).rejects.toThrow('Process exited with code 0');
|
|
275
|
+
// Should call handleTranslate without a profile
|
|
276
|
+
expect(handleTranslate).toHaveBeenCalledWith(projectDir, mockProjectConfig, 123, false, undefined);
|
|
277
|
+
expect(uiLogger.success).toHaveBeenCalledWith(commands.project.validate.success(mockProjectConfig.name));
|
|
278
|
+
});
|
|
279
|
+
it('should handle validation failure when no profiles exist', async () => {
|
|
280
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
281
|
+
projectConfig: mockProjectConfig,
|
|
282
|
+
projectDir,
|
|
283
|
+
});
|
|
284
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
285
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
286
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue([]);
|
|
287
|
+
const error = new Error('Translation failed');
|
|
288
|
+
vi.mocked(handleTranslate).mockRejectedValue(error);
|
|
289
|
+
await expect(projectValidateCommand.handler({
|
|
290
|
+
derivedAccountId: 123,
|
|
291
|
+
d: false,
|
|
292
|
+
debug: false,
|
|
293
|
+
})).rejects.toThrow('Process exited with code 1');
|
|
294
|
+
expect(uiLogger.error).toHaveBeenCalledWith(commands.project.validate.failure(mockProjectConfig.name));
|
|
295
|
+
expect(logError).toHaveBeenCalledWith(error);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
describe('source directory validation', () => {
|
|
300
|
+
it('should call validateSourceDirectory with correct parameters', async () => {
|
|
301
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
302
|
+
projectConfig: mockProjectConfig,
|
|
303
|
+
projectDir,
|
|
304
|
+
});
|
|
305
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
306
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
307
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue([]);
|
|
308
|
+
vi.mocked(handleTranslate).mockResolvedValue(undefined);
|
|
309
|
+
vi.mocked(validateSourceDirectory).mockResolvedValue(undefined);
|
|
310
|
+
await expect(projectValidateCommand.handler({
|
|
311
|
+
derivedAccountId: 123,
|
|
312
|
+
d: false,
|
|
313
|
+
debug: false,
|
|
314
|
+
})).rejects.toThrow('Process exited with code 0');
|
|
315
|
+
const expectedSrcDir = path.resolve(projectDir, mockProjectConfig.srcDir);
|
|
316
|
+
expect(validateSourceDirectory).toHaveBeenCalledWith(expectedSrcDir, mockProjectConfig, projectDir);
|
|
317
|
+
});
|
|
318
|
+
it('should exit with error when validateSourceDirectory throws', async () => {
|
|
319
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
320
|
+
projectConfig: mockProjectConfig,
|
|
321
|
+
projectDir,
|
|
322
|
+
});
|
|
323
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
324
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
325
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue([]);
|
|
326
|
+
vi.mocked(handleTranslate).mockResolvedValue(undefined);
|
|
327
|
+
const error = new Error('Invalid source directory');
|
|
328
|
+
vi.mocked(validateSourceDirectory).mockRejectedValue(error);
|
|
329
|
+
await expect(projectValidateCommand.handler({
|
|
330
|
+
derivedAccountId: 123,
|
|
331
|
+
d: false,
|
|
332
|
+
debug: false,
|
|
333
|
+
})).rejects.toThrow('Process exited with code 1');
|
|
334
|
+
expect(logError).toHaveBeenCalledWith(error);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
describe('command usage tracking', () => {
|
|
338
|
+
it('should track command usage with account type', async () => {
|
|
339
|
+
vi.mocked(getProjectConfig).mockResolvedValue({
|
|
340
|
+
projectConfig: mockProjectConfig,
|
|
341
|
+
projectDir,
|
|
342
|
+
});
|
|
343
|
+
vi.mocked(isV2Project).mockReturnValue(true);
|
|
344
|
+
vi.mocked(validateProjectConfig).mockReturnValue(undefined);
|
|
345
|
+
vi.mocked(getAllHsProfiles).mockResolvedValue([]);
|
|
346
|
+
vi.mocked(handleTranslate).mockResolvedValue(undefined);
|
|
347
|
+
vi.mocked(validateSourceDirectory).mockResolvedValue(undefined);
|
|
348
|
+
await expect(projectValidateCommand.handler({
|
|
349
|
+
derivedAccountId: 123,
|
|
350
|
+
d: false,
|
|
351
|
+
debug: false,
|
|
352
|
+
})).rejects.toThrow('Process exited with code 0');
|
|
353
|
+
expect(trackCommandUsage).toHaveBeenCalledWith('project-validate', { type: 'STANDARD' }, 123);
|
|
86
354
|
});
|
|
87
|
-
vi.mocked(trackCommandUsage);
|
|
88
|
-
vi.mocked(validateSourceDirectory).mockResolvedValue(undefined);
|
|
89
|
-
vi.mocked(handleTranslate).mockResolvedValue(undefined);
|
|
90
|
-
await expect(projectValidateCommand.handler({
|
|
91
|
-
derivedAccountId: 123,
|
|
92
|
-
d: false,
|
|
93
|
-
debug: false,
|
|
94
|
-
})).rejects.toThrow('Process exited with code 0');
|
|
95
|
-
const expectedSrcDir = path.resolve(projectDir, mockProjectConfig.srcDir);
|
|
96
|
-
expect(validateSourceDirectory).toHaveBeenCalledWith(expectedSrcDir, mockProjectConfig, projectDir);
|
|
97
355
|
});
|
|
98
356
|
});
|
|
@@ -14,7 +14,7 @@ import { cloneApp, checkCloneStatus, downloadClonedProject, } from '@hubspot/loc
|
|
|
14
14
|
import { getCwd, sanitizeFileName } from '@hubspot/local-dev-lib/path';
|
|
15
15
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
16
16
|
import { extractZipArchive } from '@hubspot/local-dev-lib/archive';
|
|
17
|
-
import {
|
|
17
|
+
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
18
18
|
import SpinniesManager from '../../lib/ui/SpinniesManager.js';
|
|
19
19
|
import { logInvalidAccountError } from '../../lib/app/migrate.js';
|
|
20
20
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
@@ -25,7 +25,7 @@ const deprecated = true;
|
|
|
25
25
|
async function handler(args) {
|
|
26
26
|
const { derivedAccountId } = args;
|
|
27
27
|
await trackCommandUsage('clone-app', {}, derivedAccountId);
|
|
28
|
-
const accountConfig =
|
|
28
|
+
const accountConfig = getConfigAccountById(derivedAccountId);
|
|
29
29
|
const accountName = uiAccountDescription(derivedAccountId);
|
|
30
30
|
if (!accountConfig) {
|
|
31
31
|
throw new Error(commands.project.cloneApp.errors.noAccountConfig(derivedAccountId));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
|
|
2
|
-
import {
|
|
2
|
+
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
4
4
|
import { isV2Project } from '../../lib/projects/platformVersion.js';
|
|
5
5
|
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
@@ -7,11 +7,10 @@ import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
|
7
7
|
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
8
8
|
import { projectNamePrompt } from '../../lib/prompts/projectNamePrompt.js';
|
|
9
9
|
import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
10
|
-
import { uiLine } from '../../lib/ui/index.js';
|
|
11
10
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
12
11
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
13
12
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
14
|
-
import { loadProfile, logProfileFooter, logProfileHeader,
|
|
13
|
+
import { loadProfile, logProfileFooter, logProfileHeader, enforceProfileUsage, } from '../../lib/projectProfiles.js';
|
|
15
14
|
import { PROJECT_DEPLOY_TEXT } from '../../lib/constants.js';
|
|
16
15
|
import { commands } from '../../lang/en.js';
|
|
17
16
|
import { handleProjectDeploy, validateBuildIdForDeploy, logDeployErrors, } from '../../lib/projects/deploy.js';
|
|
@@ -19,7 +18,7 @@ const command = 'deploy';
|
|
|
19
18
|
const describe = commands.project.deploy.describe;
|
|
20
19
|
async function handler(args) {
|
|
21
20
|
const { derivedAccountId, project: projectOption, buildId: buildIdOption, force: forceOption, deployLatestBuild: deployLatestBuildOption, json: formatOutputAsJson, } = args;
|
|
22
|
-
const accountConfig =
|
|
21
|
+
const accountConfig = getConfigAccountById(derivedAccountId);
|
|
23
22
|
const accountType = accountConfig && accountConfig.accountType;
|
|
24
23
|
let targetAccountId;
|
|
25
24
|
const jsonOutput = {};
|
|
@@ -27,9 +26,12 @@ async function handler(args) {
|
|
|
27
26
|
if (isV2Project(projectConfig?.platformVersion)) {
|
|
28
27
|
if (args.profile) {
|
|
29
28
|
logProfileHeader(args.profile);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
let profile;
|
|
30
|
+
try {
|
|
31
|
+
profile = loadProfile(projectConfig, projectDir, args.profile);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
logError(error);
|
|
33
35
|
process.exit(EXIT_CODES.ERROR);
|
|
34
36
|
}
|
|
35
37
|
targetAccountId = profile.accountId;
|
|
@@ -37,7 +39,13 @@ async function handler(args) {
|
|
|
37
39
|
}
|
|
38
40
|
else {
|
|
39
41
|
// A profile must be specified if this project has profiles configured
|
|
40
|
-
|
|
42
|
+
try {
|
|
43
|
+
await enforceProfileUsage(projectConfig, projectDir);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
logError(error);
|
|
47
|
+
process.exit(EXIT_CODES.ERROR);
|
|
48
|
+
}
|
|
41
49
|
}
|
|
42
50
|
}
|
|
43
51
|
if (!targetAccountId) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getValidEnv } from '@hubspot/local-dev-lib/environment';
|
|
1
|
+
import { getConfigAccountById, getAllConfigAccounts, getConfigAccountEnvironment, } from '@hubspot/local-dev-lib/config';
|
|
3
2
|
import { findProjectComponents, getProjectComponentTypes, } from '../../../lib/projects/structure.js';
|
|
4
3
|
import { ComponentTypes } from '../../../types/Projects.js';
|
|
5
4
|
import { commands } from '../../../lang/en.js';
|
|
@@ -14,13 +13,13 @@ import { isSandbox, isDeveloperTestAccount, } from '../../../lib/accountTypes.js
|
|
|
14
13
|
import { ensureProjectExists } from '../../../lib/projects/ensureProjectExists.js';
|
|
15
14
|
export async function deprecatedProjectDevFlow({ args, accountId, projectConfig, projectDir, }) {
|
|
16
15
|
const { userProvidedAccount, derivedAccountId } = args;
|
|
17
|
-
const env =
|
|
16
|
+
const env = getConfigAccountEnvironment(derivedAccountId);
|
|
18
17
|
const components = await findProjectComponents(projectDir);
|
|
19
18
|
const runnableComponents = components.filter(component => component.runnable);
|
|
20
19
|
const componentTypes = getProjectComponentTypes(runnableComponents);
|
|
21
20
|
const hasPrivateApps = !!componentTypes[ComponentTypes.PrivateApp];
|
|
22
21
|
const hasPublicApps = !!componentTypes[ComponentTypes.PublicApp];
|
|
23
|
-
const accountConfig =
|
|
22
|
+
const accountConfig = getConfigAccountById(accountId);
|
|
24
23
|
if (!accountConfig) {
|
|
25
24
|
uiLogger.error(commands.project.dev.errors.noAccount(accountId));
|
|
26
25
|
process.exit(EXIT_CODES.ERROR);
|
|
@@ -33,7 +32,7 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
33
32
|
uiLogger.error(commands.project.dev.errors.invalidProjectComponents);
|
|
34
33
|
process.exit(EXIT_CODES.SUCCESS);
|
|
35
34
|
}
|
|
36
|
-
const accounts =
|
|
35
|
+
const accounts = getAllConfigAccounts();
|
|
37
36
|
if (!accounts) {
|
|
38
37
|
uiLogger.error(commands.project.dev.errors.noAccountsInConfig);
|
|
39
38
|
process.exit(EXIT_CODES.ERROR);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { trackCommandUsage } from '../../../lib/usageTracking.js';
|
|
2
|
-
import {
|
|
2
|
+
import { getConfigAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/config.js';
|
|
4
4
|
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
5
5
|
import { uiLine } from '../../../lib/ui/index.js';
|
|
@@ -7,7 +7,7 @@ import { deprecatedProjectDevFlow } from './deprecatedFlow.js';
|
|
|
7
7
|
import { unifiedProjectDevFlow } from './unifiedFlow.js';
|
|
8
8
|
import { isV2Project } from '../../../lib/projects/platformVersion.js';
|
|
9
9
|
import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
|
|
10
|
-
import { loadProfile,
|
|
10
|
+
import { loadProfile, enforceProfileUsage, } from '../../../lib/projectProfiles.js';
|
|
11
11
|
import { commands } from '../../../lang/en.js';
|
|
12
12
|
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
13
13
|
import { logError } from '../../../lib/errorHandlers/index.js';
|
|
@@ -51,7 +51,8 @@ async function handler(args) {
|
|
|
51
51
|
let profile;
|
|
52
52
|
// Using the new --projectAccount flag
|
|
53
53
|
if (projectAccount) {
|
|
54
|
-
targetProjectAccountId =
|
|
54
|
+
targetProjectAccountId =
|
|
55
|
+
getConfigAccountIfExists(projectAccount)?.accountId;
|
|
55
56
|
if (targetProjectAccountId) {
|
|
56
57
|
uiLogger.log('');
|
|
57
58
|
uiLogger.log(commands.project.dev.logs.projectAccountFlagExplanation(targetProjectAccountId));
|
|
@@ -63,8 +64,11 @@ async function handler(args) {
|
|
|
63
64
|
}
|
|
64
65
|
if (!targetProjectAccountId && isV2Project(projectConfig.platformVersion)) {
|
|
65
66
|
if (args.profile) {
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
try {
|
|
68
|
+
profile = loadProfile(projectConfig, projectDir, args.profile);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
logError(error);
|
|
68
72
|
uiLine();
|
|
69
73
|
process.exit(EXIT_CODES.ERROR);
|
|
70
74
|
}
|
|
@@ -74,7 +78,13 @@ async function handler(args) {
|
|
|
74
78
|
}
|
|
75
79
|
else {
|
|
76
80
|
// A profile must be specified if this project has profiles configured
|
|
77
|
-
|
|
81
|
+
try {
|
|
82
|
+
await enforceProfileUsage(projectConfig, projectDir);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
logError(error);
|
|
86
|
+
process.exit(EXIT_CODES.ERROR);
|
|
87
|
+
}
|
|
78
88
|
}
|
|
79
89
|
}
|
|
80
90
|
if (!targetProjectAccountId) {
|
|
@@ -87,7 +97,9 @@ async function handler(args) {
|
|
|
87
97
|
}
|
|
88
98
|
trackCommandUsage('project-dev', {}, targetProjectAccountId);
|
|
89
99
|
if (isV2Project(projectConfig.platformVersion)) {
|
|
90
|
-
const targetTestingAccountId =
|
|
100
|
+
const targetTestingAccountId = testingAccount
|
|
101
|
+
? getConfigAccountIfExists(testingAccount)?.accountId
|
|
102
|
+
: undefined;
|
|
91
103
|
await unifiedProjectDevFlow({
|
|
92
104
|
args,
|
|
93
105
|
targetProjectAccountId,
|
|
@@ -4,8 +4,7 @@ import { HUBSPOT_ACCOUNT_TYPES } from '@hubspot/local-dev-lib/constants/config';
|
|
|
4
4
|
import { startPortManagerServer, stopPortManagerServer, } from '@hubspot/local-dev-lib/portManager';
|
|
5
5
|
import { isTranslationError } from '@hubspot/project-parsing-lib/src/lib/errors.js';
|
|
6
6
|
import { translateForLocalDev } from '@hubspot/project-parsing-lib';
|
|
7
|
-
import {
|
|
8
|
-
import { getValidEnv } from '@hubspot/local-dev-lib/environment';
|
|
7
|
+
import { getConfigAccountEnvironment, getAllConfigAccounts, getConfigAccountById, } from '@hubspot/local-dev-lib/config';
|
|
9
8
|
import { logError } from '../../../lib/errorHandlers/index.js';
|
|
10
9
|
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
11
10
|
import { ensureProjectExists } from '../../../lib/projects/ensureProjectExists.js';
|
|
@@ -23,7 +22,7 @@ import LocalDevWebsocketServer from '../../../lib/projects/localDev/LocalDevWebs
|
|
|
23
22
|
import { confirmLocalDevIsNotRunning } from '../../../lib/projects/localDev/helpers/process.js';
|
|
24
23
|
export async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTargetTestingAccountId, projectConfig, projectDir, }) {
|
|
25
24
|
await confirmLocalDevIsNotRunning();
|
|
26
|
-
const env =
|
|
25
|
+
const env = getConfigAccountEnvironment(targetProjectAccountId);
|
|
27
26
|
let projectNodes;
|
|
28
27
|
let projectProfileData;
|
|
29
28
|
// Get IR
|
|
@@ -50,12 +49,12 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
50
49
|
uiLogger.error(commands.project.dev.errors.noRunnableComponents);
|
|
51
50
|
process.exit(EXIT_CODES.SUCCESS);
|
|
52
51
|
}
|
|
53
|
-
const targetProjectAccountConfig =
|
|
52
|
+
const targetProjectAccountConfig = getConfigAccountById(targetProjectAccountId);
|
|
54
53
|
if (!targetProjectAccountConfig) {
|
|
55
54
|
uiLogger.error(commands.project.dev.errors.noAccount(targetProjectAccountId));
|
|
56
55
|
process.exit(EXIT_CODES.ERROR);
|
|
57
56
|
}
|
|
58
|
-
const accounts =
|
|
57
|
+
const accounts = getAllConfigAccounts();
|
|
59
58
|
const accountIsCombined = await isUnifiedAccount(targetProjectAccountConfig);
|
|
60
59
|
const targetProjectAccountIsTestAccountOrSandbox = isTestAccountOrSandbox(targetProjectAccountConfig);
|
|
61
60
|
if (!accountIsCombined) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CommonArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
export type ProjectLintArgs = CommonArgs & {
|
|
3
|
+
installMissingDeps?: boolean;
|
|
4
|
+
};
|
|
5
|
+
declare const projectLintCommand: YargsCommandModule<unknown, ProjectLintArgs>;
|
|
6
|
+
export default projectLintCommand;
|