@hubspot/cli 7.8.0-beta.0 → 7.8.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__/project.test.js +2 -0
- package/commands/account/auth.js +1 -0
- package/commands/auth.js +1 -0
- package/commands/feedback.js +1 -1
- package/commands/project/__tests__/add.test.js +12 -12
- 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 +6 -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/sandbox/delete.js +5 -2
- package/commands/testAccount/create.js +2 -2
- package/commands/theme/preview.js +1 -4
- package/lang/en.d.ts +49 -14
- package/lang/en.js +121 -86
- package/lang/en.lyaml +2 -2
- package/lib/__tests__/buildAccount.test.js +2 -2
- package/lib/app/migrate.js +1 -1
- package/lib/buildAccount.d.ts +2 -2
- package/lib/buildAccount.js +7 -7
- package/lib/configMigrate.js +88 -9
- package/lib/constants.d.ts +8 -1
- package/lib/constants.js +8 -1
- package/lib/doctor/Doctor.js +2 -2
- package/lib/errorHandlers/suppressError.js +2 -2
- package/lib/middleware/commandTargetingUtils.d.ts +1 -1
- package/lib/middleware/commandTargetingUtils.js +16 -20
- package/lib/projects/__tests__/AppDevModeInterface.test.js +85 -90
- package/lib/projects/__tests__/LocalDevProcess.test.js +6 -5
- package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +6 -6
- package/lib/projects/__tests__/deploy.test.js +9 -9
- package/lib/projects/__tests__/upload.test.js +2 -2
- 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 +8 -1
- package/lib/projects/localDev/AppDevModeInterface.js +106 -86
- package/lib/projects/localDev/DevServerManager.d.ts +11 -29
- package/lib/projects/localDev/DevServerManager.js +19 -61
- 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 +34 -2
- package/lib/projects/localDev/helpers/account.d.ts +1 -1
- package/lib/projects/localDev/helpers/account.js +2 -2
- 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__/downloadProjectPrompt.test.js +1 -0
- 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/prompts/projectDevTargetAccountPrompt.js +1 -1
- package/lib/theme/__tests__/migrate.test.js +4 -4
- package/lib/ui/index.d.ts +4 -0
- package/lib/ui/index.js +9 -1
- package/lib/ui/uiMessages.d.ts +4 -0
- package/lib/ui/uiMessages.js +4 -0
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +1 -1
- package/package.json +6 -5
- package/lib/projects/localDev/DevServerManagerV2.d.ts +0 -22
- package/lib/projects/localDev/DevServerManagerV2.js +0 -81
- /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 → add/__tests__/v2AddComponent.test.d.ts} +0 -0
- /package/lib/projects/localDev/{LocalDevManager.d.ts → LocalDevManager_DEPRECATED.d.ts} +0 -0
|
@@ -15,6 +15,7 @@ import cloneApp from '../project/cloneApp.js';
|
|
|
15
15
|
import installDeps from '../project/installDeps.js';
|
|
16
16
|
import validate from '../project/validate.js';
|
|
17
17
|
import profileCommands from '../project/profile.js';
|
|
18
|
+
import list from '../project/list.js';
|
|
18
19
|
import projectCommand from '../project.js';
|
|
19
20
|
vi.mock('../project/deploy');
|
|
20
21
|
vi.mock('../project/create');
|
|
@@ -73,6 +74,7 @@ describe('commands/project', () => {
|
|
|
73
74
|
installDeps,
|
|
74
75
|
profileCommands,
|
|
75
76
|
validate,
|
|
77
|
+
list,
|
|
76
78
|
];
|
|
77
79
|
it('should demand the command takes one positional argument', () => {
|
|
78
80
|
projectCommand.builder(yargs);
|
package/commands/account/auth.js
CHANGED
package/commands/auth.js
CHANGED
|
@@ -121,6 +121,7 @@ async function handler(args) {
|
|
|
121
121
|
await setAsDefaultAccountPrompt(accountName);
|
|
122
122
|
uiLogger.success(commands.auth.success.configFileUpdated(accountName, DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME, successAuthMethod));
|
|
123
123
|
uiFeatureHighlight([
|
|
124
|
+
'getStartedCommand',
|
|
124
125
|
'accountsUseCommand',
|
|
125
126
|
'accountOption',
|
|
126
127
|
'accountsListCommand',
|
package/commands/feedback.js
CHANGED
|
@@ -11,7 +11,7 @@ async function handler() {
|
|
|
11
11
|
const shouldOpen = await confirmPrompt(commands.project.feedback.openPrompt);
|
|
12
12
|
if (!shouldOpen) {
|
|
13
13
|
uiLogger.log(commands.project.feedback.error(FEEDBACK_URL));
|
|
14
|
-
process.exit(EXIT_CODES.
|
|
14
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
15
15
|
}
|
|
16
16
|
open(FEEDBACK_URL, { url: true });
|
|
17
17
|
uiLogger.success(commands.project.feedback.success(FEEDBACK_URL));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import yargs from 'yargs';
|
|
2
2
|
import projectAddCommand from '../add.js';
|
|
3
3
|
import { marketplaceDistribution, oAuth, privateDistribution, staticAuth, } from '../../../lib/constants.js';
|
|
4
|
-
import {
|
|
4
|
+
import { v2AddComponent } from '../../../lib/projects/add/v2AddComponent.js';
|
|
5
5
|
import { legacyAddComponent } from '../../../lib/projects/add/legacyAddComponent.js';
|
|
6
6
|
import { getProjectConfig } from '../../../lib/projects/config.js';
|
|
7
7
|
import { isV2Project } from '../../../lib/projects/platformVersion.js';
|
|
@@ -9,15 +9,15 @@ import { trackCommandUsage } from '../../../lib/usageTracking.js';
|
|
|
9
9
|
vi.mock('../../../lib/commonOpts');
|
|
10
10
|
vi.mock('../../../lib/ui/logger.js');
|
|
11
11
|
vi.mock('../../../lib/errorHandlers/index.js');
|
|
12
|
-
vi.mock('../../../lib/projects/add/
|
|
12
|
+
vi.mock('../../../lib/projects/add/v2AddComponent');
|
|
13
13
|
vi.mock('../../../lib/projects/add/legacyAddComponent');
|
|
14
14
|
vi.mock('../../../lib/projects/config');
|
|
15
15
|
vi.mock('../../../lib/projects/platformVersion');
|
|
16
16
|
vi.mock('../../../lib/usageTracking');
|
|
17
|
-
const
|
|
17
|
+
const mockedV2AddComponent = vi.mocked(v2AddComponent);
|
|
18
18
|
const mockedLegacyAddComponent = vi.mocked(legacyAddComponent);
|
|
19
19
|
const mockedGetProjectConfig = vi.mocked(getProjectConfig);
|
|
20
|
-
const
|
|
20
|
+
const mockedUseV2Api = vi.mocked(isV2Project);
|
|
21
21
|
const mockedTrackCommandUsage = vi.mocked(trackCommandUsage);
|
|
22
22
|
describe('commands/project/add', () => {
|
|
23
23
|
const yargsMock = yargs;
|
|
@@ -61,7 +61,7 @@ describe('commands/project/add', () => {
|
|
|
61
61
|
const mockProjectConfig = {
|
|
62
62
|
name: 'test-project',
|
|
63
63
|
srcDir: 'src',
|
|
64
|
-
platformVersion: '
|
|
64
|
+
platformVersion: '2025.2',
|
|
65
65
|
};
|
|
66
66
|
const mockProjectDir = '/path/to/project';
|
|
67
67
|
const mockArgs = {
|
|
@@ -75,23 +75,23 @@ describe('commands/project/add', () => {
|
|
|
75
75
|
projectDir: mockProjectDir,
|
|
76
76
|
});
|
|
77
77
|
mockedTrackCommandUsage.mockResolvedValue();
|
|
78
|
-
|
|
78
|
+
mockedV2AddComponent.mockResolvedValue();
|
|
79
79
|
mockedLegacyAddComponent.mockResolvedValue();
|
|
80
80
|
vi.spyOn(process, 'exit').mockImplementation(() => {
|
|
81
81
|
throw new Error('process.exit called');
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
|
-
it('should call
|
|
85
|
-
|
|
84
|
+
it('should call v2AddComponent with accountId for v2 projects', async () => {
|
|
85
|
+
mockedUseV2Api.mockReturnValue(true);
|
|
86
86
|
await expect(projectAddCommand.handler(mockArgs)).rejects.toThrow('process.exit called');
|
|
87
|
-
expect(
|
|
87
|
+
expect(mockedV2AddComponent).toHaveBeenCalledWith(mockArgs, mockProjectDir, mockProjectConfig, 123);
|
|
88
88
|
expect(mockedLegacyAddComponent).not.toHaveBeenCalled();
|
|
89
89
|
});
|
|
90
|
-
it('should call legacyAddComponent for non-
|
|
91
|
-
|
|
90
|
+
it('should call legacyAddComponent for non-v2 projects', async () => {
|
|
91
|
+
mockedUseV2Api.mockReturnValue(false);
|
|
92
92
|
await expect(projectAddCommand.handler(mockArgs)).rejects.toThrow('process.exit called');
|
|
93
93
|
expect(mockedLegacyAddComponent).toHaveBeenCalledWith(mockArgs, mockProjectDir, mockProjectConfig, 123);
|
|
94
|
-
expect(
|
|
94
|
+
expect(mockedV2AddComponent).not.toHaveBeenCalled();
|
|
95
95
|
});
|
|
96
96
|
it('should exit with error when project config is not found', async () => {
|
|
97
97
|
mockedGetProjectConfig.mockResolvedValue({
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import yargs from 'yargs';
|
|
2
|
+
import { addAccountOptions, addConfigOptions, } from '../../../lib/commonOpts.js';
|
|
3
|
+
import projectListCommand from '../list.js';
|
|
4
|
+
vi.mock('../../../lib/commonOpts');
|
|
5
|
+
describe('commands/project/list', () => {
|
|
6
|
+
const yargsMock = yargs;
|
|
7
|
+
describe('command', () => {
|
|
8
|
+
it('should have the correct command structure', () => {
|
|
9
|
+
expect(projectListCommand.command).toEqual(['list', 'ls']);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
describe('describe', () => {
|
|
13
|
+
it('should provide a description', () => {
|
|
14
|
+
expect(projectListCommand.describe).toBeDefined();
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
describe('builder', () => {
|
|
18
|
+
it('should support the correct options', () => {
|
|
19
|
+
projectListCommand.builder(yargsMock);
|
|
20
|
+
expect(addAccountOptions).toHaveBeenCalledTimes(1);
|
|
21
|
+
expect(addAccountOptions).toHaveBeenCalledWith(yargsMock);
|
|
22
|
+
expect(addConfigOptions).toHaveBeenCalledTimes(1);
|
|
23
|
+
expect(addConfigOptions).toHaveBeenCalledWith(yargsMock);
|
|
24
|
+
});
|
|
25
|
+
it('should define examples', () => {
|
|
26
|
+
const exampleSpy = vi.spyOn(yargsMock, 'example');
|
|
27
|
+
projectListCommand.builder(yargsMock);
|
|
28
|
+
expect(exampleSpy).toHaveBeenCalled();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -10,6 +10,7 @@ vi.mock('../../../lib/ui/logger.js');
|
|
|
10
10
|
vi.mock('../../../lib/app/migrate');
|
|
11
11
|
vi.mock('../../../lib/projects/config');
|
|
12
12
|
vi.mock('../../../lib/ui');
|
|
13
|
+
vi.mock('../../../lib/usageTracking.js');
|
|
13
14
|
const { v2025_2 } = PLATFORM_VERSIONS;
|
|
14
15
|
describe('commands/project/migrate', () => {
|
|
15
16
|
const yargsMock = yargs;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { YargsCommandModule, CommonArgs } from '../../types/Yargs.js';
|
|
2
|
-
export type ProjectAddArgs = CommonArgs & {
|
|
1
|
+
import { YargsCommandModule, CommonArgs, ConfigArgs } from '../../types/Yargs.js';
|
|
2
|
+
export type ProjectAddArgs = CommonArgs & ConfigArgs & {
|
|
3
3
|
type?: string;
|
|
4
4
|
name?: string;
|
|
5
5
|
features?: string[];
|
package/commands/project/add.js
CHANGED
|
@@ -5,7 +5,7 @@ import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
|
5
5
|
import { commands } from '../../lang/en.js';
|
|
6
6
|
import { isV2Project } from '../../lib/projects/platformVersion.js';
|
|
7
7
|
import { legacyAddComponent } from '../../lib/projects/add/legacyAddComponent.js';
|
|
8
|
-
import {
|
|
8
|
+
import { v2AddComponent } from '../../lib/projects/add/v2AddComponent.js';
|
|
9
9
|
import { marketplaceDistribution, oAuth, privateDistribution, staticAuth, } from '../../lib/constants.js';
|
|
10
10
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
11
11
|
const command = 'add';
|
|
@@ -20,7 +20,7 @@ async function handler(args) {
|
|
|
20
20
|
}
|
|
21
21
|
const isV2ProjectCreate = isV2Project(projectConfig.platformVersion);
|
|
22
22
|
if (isV2ProjectCreate) {
|
|
23
|
-
await
|
|
23
|
+
await v2AddComponent(args, projectDir, projectConfig, derivedAccountId);
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
26
|
await legacyAddComponent(args, projectDir, projectConfig, derivedAccountId);
|
|
@@ -68,6 +68,7 @@ function projectAddBuilder(yargs) {
|
|
|
68
68
|
}
|
|
69
69
|
const builder = makeYargsBuilder(projectAddBuilder, command, describe, {
|
|
70
70
|
useGlobalOptions: true,
|
|
71
|
+
useConfigOptions: true,
|
|
71
72
|
});
|
|
72
73
|
const projectAddCommand = {
|
|
73
74
|
command,
|
|
@@ -5,7 +5,7 @@ import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
|
5
5
|
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
6
6
|
import { writeProjectConfig, getProjectConfig, } from '../../lib/projects/config.js';
|
|
7
7
|
import { EMPTY_PROJECT_TEMPLATE_NAME } from '../../lib/projects/create/legacy.js';
|
|
8
|
-
import { generateComponentPaths } from '../../lib/projects/create/
|
|
8
|
+
import { generateComponentPaths } from '../../lib/projects/create/v2.js';
|
|
9
9
|
import { PROJECT_WITH_APP, EMPTY_PROJECT } from '../../lib/constants.js';
|
|
10
10
|
import { uiFeatureHighlight } from '../../lib/ui/index.js';
|
|
11
11
|
import { debugError, logError } from '../../lib/errorHandlers/index.js';
|
|
@@ -6,7 +6,7 @@ import { commands } from '../../../lang/en.js';
|
|
|
6
6
|
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
7
7
|
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
8
8
|
import SpinniesManager from '../../../lib/ui/SpinniesManager.js';
|
|
9
|
-
import
|
|
9
|
+
import LocalDevManager_DEPRECATED from '../../../lib/projects/localDev/LocalDevManager_DEPRECATED.js';
|
|
10
10
|
import { confirmDefaultAccountIsTarget, suggestRecommendedNestedAccount, checkIfAccountFlagIsSupported, checkIfDefaultAccountIsSupported, createSandboxForLocalDev, createDeveloperTestAccountForLocalDev, useExistingDevTestAccount, checkIfParentAccountIsAuthed, hasSandboxes, } from '../../../lib/projects/localDev/helpers/account.js';
|
|
11
11
|
import { createInitialBuildForNewProject, createNewProjectForLocalDev, } from '../../../lib/projects/localDev/helpers/project.js';
|
|
12
12
|
import { handleExit } from '../../../lib/process.js';
|
|
@@ -121,7 +121,7 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
121
121
|
project = await createNewProjectForLocalDev(projectConfig, targetProjectAccountId, createNewSandbox, hasPublicApps);
|
|
122
122
|
deployedBuild = await createInitialBuildForNewProject(projectConfig, projectDir, targetProjectAccountId);
|
|
123
123
|
}
|
|
124
|
-
const LocalDev = new
|
|
124
|
+
const LocalDev = new LocalDevManager_DEPRECATED({
|
|
125
125
|
runnableComponents,
|
|
126
126
|
debug: args.debug,
|
|
127
127
|
deployedBuild,
|
|
@@ -12,14 +12,14 @@ import { commands } from '../../../lang/en.js';
|
|
|
12
12
|
import { uiLogger } from '../../../lib/ui/logger.js';
|
|
13
13
|
const command = 'dev';
|
|
14
14
|
const describe = commands.project.dev.describe;
|
|
15
|
-
function validateAccountFlags(testingAccount, projectAccount, userProvidedAccount,
|
|
15
|
+
function validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV2) {
|
|
16
16
|
// Legacy projects do not support targetTestingAccount and targetProjectAccount
|
|
17
|
-
if (testingAccount && projectAccount && !
|
|
17
|
+
if (testingAccount && projectAccount && !useV2) {
|
|
18
18
|
uiLogger.error(commands.project.dev.errors.unsupportedAccountFlagLegacy);
|
|
19
19
|
process.exit(EXIT_CODES.ERROR);
|
|
20
20
|
}
|
|
21
|
-
if (userProvidedAccount &&
|
|
22
|
-
uiLogger.error(commands.project.dev.errors.
|
|
21
|
+
if (userProvidedAccount && useV2) {
|
|
22
|
+
uiLogger.error(commands.project.dev.errors.unsupportedAccountFlagV2);
|
|
23
23
|
process.exit(EXIT_CODES.ERROR);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -35,7 +35,7 @@ async function handler(args) {
|
|
|
35
35
|
validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV2Projects);
|
|
36
36
|
uiLogger.log(commands.project.dev.logs.header);
|
|
37
37
|
if (useV2Projects) {
|
|
38
|
-
uiLogger.log(commands.project.dev.logs.
|
|
38
|
+
uiLogger.log(commands.project.dev.logs.learnMoreMessageV2);
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
41
41
|
uiLogger.log(commands.project.dev.logs.learnMoreMessageLegacy);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import util from 'util';
|
|
3
3
|
import { HUBSPOT_ACCOUNT_TYPES } from '@hubspot/local-dev-lib/constants/config';
|
|
4
|
+
import { startPortManagerServer, stopPortManagerServer, } from '@hubspot/local-dev-lib/portManager';
|
|
4
5
|
import { isTranslationError } from '@hubspot/project-parsing-lib/src/lib/errors.js';
|
|
5
6
|
import { translateForLocalDev } from '@hubspot/project-parsing-lib';
|
|
6
7
|
import { getEnv, getConfigAccounts, getAccountConfig, } from '@hubspot/local-dev-lib/config';
|
|
@@ -121,6 +122,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
121
122
|
// Check for missing/outdated dependencies
|
|
122
123
|
await checkAndInstallDependencies();
|
|
123
124
|
// End setup, start local dev process
|
|
125
|
+
await startPortManagerServer();
|
|
124
126
|
const localDevProcess = new LocalDevProcess({
|
|
125
127
|
initialProjectNodes: projectNodes,
|
|
126
128
|
initialProjectProfileData: projectProfileData,
|
|
@@ -133,11 +135,11 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
133
135
|
projectData: project,
|
|
134
136
|
env,
|
|
135
137
|
});
|
|
136
|
-
await localDevProcess.start();
|
|
137
|
-
const watcher = new LocalDevWatcher(localDevProcess);
|
|
138
|
-
watcher.start();
|
|
139
138
|
const websocketServer = new LocalDevWebsocketServer(localDevProcess, args.debug);
|
|
139
|
+
const watcher = new LocalDevWatcher(localDevProcess);
|
|
140
140
|
await websocketServer.start();
|
|
141
|
+
await localDevProcess.start();
|
|
142
|
+
watcher.start();
|
|
141
143
|
handleKeypress(async (key) => {
|
|
142
144
|
if ((key.ctrl && key.name === 'c') || key.name === 'q') {
|
|
143
145
|
await Promise.all([
|
|
@@ -151,5 +153,6 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
151
153
|
localDevProcess.stop(!isSIGHUP);
|
|
152
154
|
watcher.stop();
|
|
153
155
|
websocketServer.shutdown();
|
|
156
|
+
stopPortManagerServer();
|
|
154
157
|
});
|
|
155
158
|
}
|
|
@@ -35,9 +35,12 @@ async function handler(args) {
|
|
|
35
35
|
uiLogger.error(commands.project.download.errors.noBuildIdToDownload);
|
|
36
36
|
process.exit(EXIT_CODES.ERROR);
|
|
37
37
|
}
|
|
38
|
-
const
|
|
38
|
+
const sanitizedProjectName = sanitizeFileName(projectName);
|
|
39
|
+
const absoluteDestPath = dest
|
|
40
|
+
? path.resolve(getCwd(), dest, sanitizedProjectName)
|
|
41
|
+
: path.resolve(getCwd(), sanitizedProjectName);
|
|
39
42
|
const { data: zippedProject } = await downloadProject(derivedAccountId, projectName, buildNumberToDownload);
|
|
40
|
-
await extractZipArchive(zippedProject, sanitizeFileName(projectName), path.resolve(absoluteDestPath)
|
|
43
|
+
await extractZipArchive(zippedProject, sanitizeFileName(projectName), path.resolve(absoluteDestPath));
|
|
41
44
|
uiLogger.log(commands.project.download.logs.downloadSucceeded(buildNumberToDownload, projectName));
|
|
42
45
|
process.exit(EXIT_CODES.SUCCESS);
|
|
43
46
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CommonArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
export type ProjectInstallDepsArgs = CommonArgs & {
|
|
1
|
+
import { CommonArgs, ConfigArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
export type ProjectInstallDepsArgs = CommonArgs & ConfigArgs & {
|
|
3
3
|
packages?: string[];
|
|
4
4
|
};
|
|
5
5
|
declare const projectInstallDepsCommand: YargsCommandModule<unknown, ProjectInstallDepsArgs>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AccountArgs, CommonArgs, ConfigArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
type ProjectListArgs = CommonArgs & ConfigArgs & AccountArgs;
|
|
3
|
+
declare const projectListCommand: YargsCommandModule<unknown, ProjectListArgs>;
|
|
4
|
+
export default projectListCommand;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
2
|
+
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
3
|
+
import { fetchProjects } from '@hubspot/local-dev-lib/api/projects';
|
|
4
|
+
import { logError } from '../../lib/errorHandlers/index.js';
|
|
5
|
+
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
6
|
+
import { getTableContents, getTableHeader } from '../../lib/ui/table.js';
|
|
7
|
+
import { uiLogger } from '../../lib/ui/logger.js';
|
|
8
|
+
import { commands } from '../../lang/en.js';
|
|
9
|
+
const command = ['list', 'ls'];
|
|
10
|
+
const describe = commands.project.list.describe;
|
|
11
|
+
async function getProjectData(accountId) {
|
|
12
|
+
try {
|
|
13
|
+
const { data: projects } = await fetchProjects(accountId);
|
|
14
|
+
return projects.results;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
logError(e);
|
|
18
|
+
process.exit(EXIT_CODES.ERROR);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function formatProjectsAsTableRows(projects) {
|
|
22
|
+
const projectListData = [];
|
|
23
|
+
projects.forEach(project => {
|
|
24
|
+
projectListData.push([
|
|
25
|
+
project.name,
|
|
26
|
+
project.latestBuild ? project.latestBuild.platformVersion : '',
|
|
27
|
+
]);
|
|
28
|
+
});
|
|
29
|
+
return projectListData;
|
|
30
|
+
}
|
|
31
|
+
async function handler(args) {
|
|
32
|
+
const { derivedAccountId } = args;
|
|
33
|
+
trackCommandUsage('projects-list', undefined, derivedAccountId);
|
|
34
|
+
const projectData = await getProjectData(derivedAccountId);
|
|
35
|
+
if (projectData.length === 0) {
|
|
36
|
+
uiLogger.error(commands.project.list.errors.noProjectsFound(derivedAccountId));
|
|
37
|
+
process.exit(EXIT_CODES.ERROR);
|
|
38
|
+
}
|
|
39
|
+
const projectListData = formatProjectsAsTableRows(projectData);
|
|
40
|
+
projectListData.unshift(getTableHeader([
|
|
41
|
+
commands.project.list.labels.name,
|
|
42
|
+
commands.project.list.labels.platformVersion,
|
|
43
|
+
]));
|
|
44
|
+
uiLogger.log(commands.project.list.projects);
|
|
45
|
+
uiLogger.log(getTableContents(projectListData, { border: { bodyLeft: ' ' } }));
|
|
46
|
+
}
|
|
47
|
+
function projectListBuilder(yargs) {
|
|
48
|
+
yargs.example([['$0 project list']]);
|
|
49
|
+
return yargs;
|
|
50
|
+
}
|
|
51
|
+
const builder = makeYargsBuilder(projectListBuilder, command, describe, {
|
|
52
|
+
useGlobalOptions: true,
|
|
53
|
+
useConfigOptions: true,
|
|
54
|
+
useAccountOptions: true,
|
|
55
|
+
});
|
|
56
|
+
const projectListCommand = {
|
|
57
|
+
command,
|
|
58
|
+
describe,
|
|
59
|
+
handler,
|
|
60
|
+
builder,
|
|
61
|
+
};
|
|
62
|
+
export default projectListCommand;
|
|
@@ -13,11 +13,13 @@ import { getWarningBox } from '../../ui/components/StatusMessageBoxes.js';
|
|
|
13
13
|
import { getHasMigratableThemes, migrateThemes2025_2, } from '../../lib/theme/migrate.js';
|
|
14
14
|
import { hasFeature } from '../../lib/hasFeature.js';
|
|
15
15
|
import { FEATURES } from '../../lib/constants.js';
|
|
16
|
+
import { trackCommandMetadataUsage, trackCommandUsage, } from '../../lib/usageTracking.js';
|
|
16
17
|
const { v2025_2 } = PLATFORM_VERSIONS;
|
|
17
18
|
const command = 'migrate';
|
|
18
19
|
const describe = commands.project.migrate.describe;
|
|
19
20
|
async function handler(args) {
|
|
20
|
-
const { platformVersion, unstable } = args;
|
|
21
|
+
const { platformVersion, unstable, derivedAccountId } = args;
|
|
22
|
+
await trackCommandUsage('project-migrate', {}, derivedAccountId);
|
|
21
23
|
const projectConfig = await getProjectConfig();
|
|
22
24
|
if (!projectConfig.projectConfig) {
|
|
23
25
|
uiLogger.error(commands.project.migrate.errors.noProjectConfig(uiCommandReference('hs app migrate')));
|
|
@@ -37,7 +39,6 @@ async function handler(args) {
|
|
|
37
39
|
}));
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
|
-
const { derivedAccountId } = args;
|
|
41
42
|
try {
|
|
42
43
|
const { hasMigratableThemes, migratableThemesCount } = await getHasMigratableThemes(projectConfig);
|
|
43
44
|
if (hasMigratableThemes) {
|
|
@@ -64,9 +65,11 @@ async function handler(args) {
|
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
catch (error) {
|
|
68
|
+
await trackCommandMetadataUsage('project-migrate', { successful: false }, derivedAccountId);
|
|
67
69
|
logError(error);
|
|
68
70
|
return process.exit(EXIT_CODES.ERROR);
|
|
69
71
|
}
|
|
72
|
+
await trackCommandMetadataUsage('project-migrate', { successful: true }, derivedAccountId);
|
|
70
73
|
return process.exit(EXIT_CODES.SUCCESS);
|
|
71
74
|
}
|
|
72
75
|
function projectMigrateBuilder(yargs) {
|
package/commands/project.js
CHANGED
|
@@ -15,6 +15,7 @@ import cloneApp from './project/cloneApp.js';
|
|
|
15
15
|
import installDeps from './project/installDeps.js';
|
|
16
16
|
import profile from './project/profile.js';
|
|
17
17
|
import projectValidate from './project/validate.js';
|
|
18
|
+
import list from './project/list.js';
|
|
18
19
|
import { makeYargsBuilder } from '../lib/yargsUtils.js';
|
|
19
20
|
const command = ['project', 'projects'];
|
|
20
21
|
const describe = commands.project.describe;
|
|
@@ -23,6 +24,7 @@ function projectBuilder(yargs) {
|
|
|
23
24
|
.command(create)
|
|
24
25
|
.command(add)
|
|
25
26
|
.command(watch)
|
|
27
|
+
.command(list)
|
|
26
28
|
.command(dev)
|
|
27
29
|
.command(upload)
|
|
28
30
|
.command(deploy)
|
|
@@ -12,7 +12,7 @@ import { deleteSandboxPrompt } from '../../lib/prompts/sandboxesPrompt.js';
|
|
|
12
12
|
import { selectAccountFromConfig } from '../../lib/prompts/accountsPrompt.js';
|
|
13
13
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
14
14
|
import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
15
|
-
import { uiBetaTag } from '../../lib/ui/index.js';
|
|
15
|
+
import { uiAuthCommandReference, uiBetaTag } from '../../lib/ui/index.js';
|
|
16
16
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
17
17
|
const command = 'delete';
|
|
18
18
|
const describe = uiBetaTag(commands.sandbox.subcommands.delete.describe, false);
|
|
@@ -65,7 +65,10 @@ async function handler(args) {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
const url = `${baseUrl}/sandboxes/${parentAccountId}`;
|
|
68
|
-
const command =
|
|
68
|
+
const command = uiAuthCommandReference({
|
|
69
|
+
accountId: parentAccountId || undefined,
|
|
70
|
+
qa: getEnv(sandboxAccountId) === 'qa',
|
|
71
|
+
});
|
|
69
72
|
if (parentAccountId && !getAccountId(parentAccountId)) {
|
|
70
73
|
uiLogger.log('');
|
|
71
74
|
uiLogger.error(commands.sandbox.subcommands.delete.failure.noParentPortalAvailable(command, url));
|
|
@@ -13,7 +13,7 @@ import { commands } from '../../lang/en.js';
|
|
|
13
13
|
import { createDeveloperTestAccountConfigPrompt } from '../../lib/prompts/createDeveloperTestAccountConfigPrompt.js';
|
|
14
14
|
import { debugError, logError } from '../../lib/errorHandlers/index.js';
|
|
15
15
|
import SpinniesManager from '../../lib/ui/SpinniesManager.js';
|
|
16
|
-
import {
|
|
16
|
+
import { createDeveloperTestAccountV2, saveAccountToConfig, } from '../../lib/buildAccount.js';
|
|
17
17
|
const command = 'create';
|
|
18
18
|
const describe = commands.testAccount.create.describe;
|
|
19
19
|
async function handler(args) {
|
|
@@ -69,7 +69,7 @@ async function handler(args) {
|
|
|
69
69
|
text: commands.testAccount.create.polling.start(testAccountConfig.accountName),
|
|
70
70
|
});
|
|
71
71
|
try {
|
|
72
|
-
const createResult = await
|
|
72
|
+
const createResult = await createDeveloperTestAccountV2(derivedAccountId, testAccountConfig);
|
|
73
73
|
resultJson.accountName = createResult.accountName;
|
|
74
74
|
resultJson.accountId = createResult.accountId;
|
|
75
75
|
resultJson.personalAccessKey = createResult.personalAccessKey;
|
|
@@ -15,8 +15,6 @@ import { handleExit, handleKeypress } from '../../lib/process.js';
|
|
|
15
15
|
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
16
16
|
import { findProjectComponents } from '../../lib/projects/structure.js';
|
|
17
17
|
import { ComponentTypes } from '../../types/Projects.js';
|
|
18
|
-
import { hasFeature } from '../../lib/hasFeature.js';
|
|
19
|
-
import { FEATURES } from '../../lib/constants.js';
|
|
20
18
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
21
19
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
22
20
|
const command = 'preview [--src] [--dest]';
|
|
@@ -150,8 +148,7 @@ async function handler(args) {
|
|
|
150
148
|
catch (e) {
|
|
151
149
|
uiLogger.warn('Unified dev server requires node 20 to run. Defaulting to legacy preview.');
|
|
152
150
|
}
|
|
153
|
-
|
|
154
|
-
if (isUngatedForUnified && createUnifiedDevServer) {
|
|
151
|
+
if (createUnifiedDevServer) {
|
|
155
152
|
if (port) {
|
|
156
153
|
process.env['PORT'] = port.toString();
|
|
157
154
|
}
|