@hubspot/cli 7.7.27-experimental.1 → 7.7.28-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/README.md +0 -4
- package/api/__tests__/migrate.test.js +5 -5
- package/api/migrate.d.ts +10 -4
- package/api/migrate.js +2 -2
- package/commands/__tests__/create.test.js +20 -0
- package/commands/__tests__/testAccount.test.js +2 -0
- package/commands/app/__tests__/migrate.test.js +1 -0
- package/commands/create/function.js +2 -2
- package/commands/create/module.js +2 -2
- package/commands/create/template.js +2 -2
- package/commands/create.js +47 -0
- package/commands/getStarted.js +66 -4
- package/commands/mcp/setup.d.ts +0 -1
- package/commands/mcp/setup.js +3 -11
- package/commands/project/__tests__/create.test.js +57 -0
- package/commands/project/__tests__/devUnifiedFlow.test.js +18 -30
- package/commands/project/create.js +6 -1
- package/commands/project/deploy.js +31 -1
- package/commands/project/dev/deprecatedFlow.js +2 -1
- package/commands/project/dev/index.js +32 -12
- package/commands/project/dev/unifiedFlow.d.ts +1 -1
- package/commands/project/dev/unifiedFlow.js +10 -16
- package/commands/project/profile/delete.js +26 -14
- package/commands/project/upload.d.ts +2 -2
- package/commands/project/upload.js +1 -1
- package/commands/testAccount/__tests__/importData.test.d.ts +1 -0
- package/commands/testAccount/__tests__/importData.test.js +93 -0
- package/commands/testAccount/create.js +23 -13
- package/commands/testAccount/importData.d.ts +9 -0
- package/commands/testAccount/importData.js +61 -0
- package/commands/testAccount.js +2 -0
- package/lang/en.d.ts +160 -46
- package/lang/en.js +175 -59
- package/lang/en.lyaml +35 -14
- package/lib/__tests__/importData.test.d.ts +1 -0
- package/lib/__tests__/importData.test.js +89 -0
- package/lib/accountTypes.js +2 -3
- package/lib/app/__tests__/migrate.test.js +81 -36
- package/lib/app/migrate.d.ts +17 -4
- package/lib/app/migrate.js +97 -19
- package/lib/constants.d.ts +1 -0
- package/lib/constants.js +1 -0
- package/lib/hasFeature.d.ts +1 -0
- package/lib/hasFeature.js +7 -0
- package/lib/importData.d.ts +3 -0
- package/lib/importData.js +50 -0
- package/lib/mcp/setup.d.ts +0 -2
- package/lib/mcp/setup.js +0 -24
- package/lib/process.js +15 -4
- package/lib/projectProfiles.d.ts +1 -1
- package/lib/projectProfiles.js +10 -2
- package/lib/projects/__tests__/AppDevModeInterface.test.js +3 -3
- package/lib/projects/__tests__/LocalDevProcess.test.js +5 -95
- package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +6 -6
- package/lib/projects/__tests__/components.test.js +164 -7
- package/lib/projects/__tests__/localDevProjectHelpers.test.d.ts +1 -0
- package/lib/projects/__tests__/localDevProjectHelpers.test.js +118 -0
- package/lib/projects/add/v3AddComponent.js +16 -4
- package/lib/projects/components.d.ts +1 -0
- package/lib/projects/components.js +27 -1
- package/lib/projects/localDev/AppDevModeInterface.js +35 -3
- package/lib/projects/localDev/LocalDevLogger.d.ts +0 -4
- package/lib/projects/localDev/LocalDevLogger.js +2 -19
- package/lib/projects/localDev/LocalDevManager.js +1 -1
- package/lib/projects/localDev/LocalDevProcess.d.ts +1 -2
- package/lib/projects/localDev/LocalDevProcess.js +3 -26
- package/lib/projects/localDev/LocalDevState.d.ts +6 -7
- package/lib/projects/localDev/LocalDevState.js +16 -15
- package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +1 -0
- package/lib/projects/localDev/LocalDevWebsocketServer.js +17 -2
- package/lib/projects/localDev/{helpers.d.ts → helpers/account.d.ts} +1 -7
- package/lib/projects/localDev/{helpers.js → helpers/account.js} +44 -144
- package/lib/projects/localDev/helpers/project.d.ts +12 -0
- package/lib/projects/localDev/helpers/project.js +173 -0
- package/lib/projects/urls.d.ts +1 -0
- package/lib/projects/urls.js +4 -0
- package/lib/prompts/__tests__/createFunctionPrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/createFunctionPrompt.test.js +129 -0
- package/lib/prompts/__tests__/createModulePrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/createModulePrompt.test.js +187 -0
- package/lib/prompts/__tests__/createTemplatePrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/createTemplatePrompt.test.js +102 -0
- package/lib/prompts/confirmImportDataPrompt.d.ts +1 -0
- package/lib/prompts/confirmImportDataPrompt.js +12 -0
- package/lib/prompts/createFunctionPrompt.d.ts +2 -1
- package/lib/prompts/createFunctionPrompt.js +36 -7
- package/lib/prompts/createModulePrompt.d.ts +2 -1
- package/lib/prompts/createModulePrompt.js +48 -1
- package/lib/prompts/createTemplatePrompt.d.ts +3 -24
- package/lib/prompts/createTemplatePrompt.js +9 -1
- package/lib/prompts/importDataFilePathPrompt.d.ts +1 -0
- package/lib/prompts/importDataFilePathPrompt.js +24 -0
- package/lib/prompts/importDataTestAccountSelectPrompt.d.ts +3 -0
- package/lib/prompts/importDataTestAccountSelectPrompt.js +29 -0
- package/lib/prompts/projectDevTargetAccountPrompt.js +1 -0
- package/lib/prompts/promptUtils.d.ts +7 -1
- package/lib/prompts/promptUtils.js +14 -1
- package/lib/ui/__tests__/removeAnsiCodes.test.d.ts +1 -0
- package/lib/ui/__tests__/removeAnsiCodes.test.js +84 -0
- package/lib/ui/index.js +3 -6
- package/lib/ui/removeAnsiCodes.d.ts +1 -0
- package/lib/ui/removeAnsiCodes.js +4 -0
- package/mcp-server/server.js +2 -1
- package/mcp-server/tools/cms/HsListTool.d.ts +23 -0
- package/mcp-server/tools/cms/HsListTool.js +58 -0
- package/mcp-server/tools/cms/__tests__/HsListTool.test.d.ts +1 -0
- package/mcp-server/tools/cms/__tests__/HsListTool.test.js +120 -0
- package/mcp-server/tools/index.d.ts +1 -0
- package/mcp-server/tools/index.js +8 -0
- package/mcp-server/tools/project/DocFetchTool.d.ts +17 -0
- package/mcp-server/tools/project/DocFetchTool.js +49 -0
- package/mcp-server/tools/project/DocsSearchTool.d.ts +26 -0
- package/mcp-server/tools/project/DocsSearchTool.js +62 -0
- package/mcp-server/tools/project/GetConfigValuesTool.js +3 -2
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +117 -0
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +190 -0
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +1 -1
- package/mcp-server/tools/project/constants.d.ts +2 -0
- package/mcp-server/tools/project/constants.js +6 -0
- package/mcp-server/utils/toolUsageTracking.d.ts +3 -1
- package/mcp-server/utils/toolUsageTracking.js +2 -1
- package/package.json +9 -6
- package/types/Cms.d.ts +16 -0
- package/types/Cms.js +25 -1
- package/types/LocalDev.d.ts +0 -3
- package/types/Prompts.d.ts +1 -0
- package/types/Yargs.d.ts +1 -1
- package/ui/index.d.ts +1 -0
- package/ui/index.js +6 -0
package/README.md
CHANGED
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
A CLI for HubSpot developers to enable local development and automation. [Learn more about building on HubSpot](https://developers.hubspot.com).
|
|
6
6
|
|
|
7
|
-
## Contributing
|
|
8
|
-
|
|
9
|
-
For more information on developing, see the [Contributing Guide](CONTRIBUTING.md).
|
|
10
|
-
|
|
11
7
|
## Getting started
|
|
12
8
|
|
|
13
9
|
For more information on using these tools, see [Local Development Tooling: Getting Started](https://developers.hubspot.com/docs/cms/guides/getting-started-with-local-development)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { http } from '@hubspot/local-dev-lib/http';
|
|
2
2
|
import { MIGRATION_STATUS } from '@hubspot/local-dev-lib/types/Migration';
|
|
3
|
-
import { listAppsForMigration,
|
|
3
|
+
import { listAppsForMigration, initializeAppMigration, continueAppMigration, checkMigrationStatusV2, isMigrationStatus, } from '../migrate.js';
|
|
4
4
|
vi.mock('@hubspot/local-dev-lib/http');
|
|
5
5
|
const httpMock = http;
|
|
6
6
|
describe('api/migrate', () => {
|
|
@@ -49,12 +49,12 @@ describe('api/migrate', () => {
|
|
|
49
49
|
expect(result).toEqual(mockResponse);
|
|
50
50
|
});
|
|
51
51
|
});
|
|
52
|
-
describe('
|
|
52
|
+
describe('initializeAppMigration', () => {
|
|
53
53
|
it('should call http.post with correct parameters', async () => {
|
|
54
54
|
const mockResponse = { migrationId: mockMigrationId };
|
|
55
55
|
// @ts-expect-error Mock
|
|
56
56
|
httpMock.post.mockResolvedValue(mockResponse);
|
|
57
|
-
const result = await
|
|
57
|
+
const result = await initializeAppMigration(mockAccountId, mockAppId, mockPlatformVersion);
|
|
58
58
|
expect(http.post).toHaveBeenCalledWith(mockAccountId, {
|
|
59
59
|
url: 'dfs/migrations/v2/migrations',
|
|
60
60
|
data: {
|
|
@@ -65,12 +65,12 @@ describe('api/migrate', () => {
|
|
|
65
65
|
expect(result).toEqual(mockResponse);
|
|
66
66
|
});
|
|
67
67
|
});
|
|
68
|
-
describe('
|
|
68
|
+
describe('continueAppMigration', () => {
|
|
69
69
|
it('should call http.post with correct parameters', async () => {
|
|
70
70
|
const mockResponse = { migrationId: mockMigrationId };
|
|
71
71
|
// @ts-expect-error Mock
|
|
72
72
|
httpMock.post.mockResolvedValue(mockResponse);
|
|
73
|
-
const result = await
|
|
73
|
+
const result = await continueAppMigration(mockPortalId, mockMigrationId, mockComponentUids, mockProjectName);
|
|
74
74
|
expect(http.post).toHaveBeenCalledWith(mockPortalId, {
|
|
75
75
|
url: 'dfs/migrations/v2/migrations/continue',
|
|
76
76
|
data: {
|
package/api/migrate.d.ts
CHANGED
|
@@ -24,7 +24,13 @@ export interface ListAppsResponse {
|
|
|
24
24
|
migratableApps: MigratableApp[];
|
|
25
25
|
unmigratableApps: UnmigratableApp[];
|
|
26
26
|
}
|
|
27
|
-
export interface
|
|
27
|
+
export interface ListThemesResponse {
|
|
28
|
+
migratableThemes: {
|
|
29
|
+
THEME: string[];
|
|
30
|
+
REACT_THEME: string[];
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export interface InitializeAppMigrationResponse {
|
|
28
34
|
migrationId: number;
|
|
29
35
|
}
|
|
30
36
|
export interface ListAppsMigrationComponent {
|
|
@@ -32,7 +38,7 @@ export interface ListAppsMigrationComponent {
|
|
|
32
38
|
componentType: string;
|
|
33
39
|
isSupported: boolean;
|
|
34
40
|
}
|
|
35
|
-
export type
|
|
41
|
+
export type ContinueAppMigrationResponse = {
|
|
36
42
|
migrationId: number;
|
|
37
43
|
};
|
|
38
44
|
export interface MigrationBaseStatus {
|
|
@@ -65,7 +71,7 @@ export interface MigrationFailed extends MigrationBaseStatus {
|
|
|
65
71
|
export type MigrationStatus = MigrationInProgress | MigrationInputRequired | MigrationSuccess | MigrationFailed;
|
|
66
72
|
export declare function isMigrationStatus(error: unknown): error is MigrationStatus;
|
|
67
73
|
export declare function listAppsForMigration(accountId: number, platformVersion: string): HubSpotPromise<ListAppsResponse>;
|
|
68
|
-
export declare function
|
|
69
|
-
export declare function
|
|
74
|
+
export declare function initializeAppMigration(accountId: number, applicationId: number, platformVersion: string): HubSpotPromise<InitializeAppMigrationResponse>;
|
|
75
|
+
export declare function continueAppMigration(portalId: number, migrationId: number, componentUids: Record<string, string>, projectName: string): HubSpotPromise<ContinueAppMigrationResponse>;
|
|
70
76
|
export declare function checkMigrationStatusV2(accountId: number, id: number): HubSpotPromise<MigrationStatus>;
|
|
71
77
|
export {};
|
package/api/migrate.js
CHANGED
|
@@ -24,7 +24,7 @@ function mapPlatformVersionToEnum(platformVersion) {
|
|
|
24
24
|
}
|
|
25
25
|
return `V${platformVersion.replace('.', '_')}`;
|
|
26
26
|
}
|
|
27
|
-
export async function
|
|
27
|
+
export async function initializeAppMigration(accountId, applicationId, platformVersion) {
|
|
28
28
|
return http.post(accountId, {
|
|
29
29
|
url: `${MIGRATIONS_API_PATH_V2}/migrations`,
|
|
30
30
|
data: {
|
|
@@ -33,7 +33,7 @@ export async function initializeMigration(accountId, applicationId, platformVers
|
|
|
33
33
|
},
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
|
-
export async function
|
|
36
|
+
export async function continueAppMigration(portalId, migrationId, componentUids, projectName) {
|
|
37
37
|
return http.post(portalId, {
|
|
38
38
|
url: `${MIGRATIONS_API_PATH_V2}/migrations/continue`,
|
|
39
39
|
data: {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import yargs from 'yargs';
|
|
2
2
|
import createCommand from '../create.js';
|
|
3
|
+
import { TEMPLATE_TYPES, HTTP_METHODS } from '../../types/Cms.js';
|
|
3
4
|
const positionalSpy = vi
|
|
4
5
|
.spyOn(yargs, 'positional')
|
|
5
6
|
.mockReturnValue(yargs);
|
|
@@ -28,6 +29,25 @@ describe('commands/create', () => {
|
|
|
28
29
|
it('should support the correct options', () => {
|
|
29
30
|
createCommand.builder(yargs);
|
|
30
31
|
expect(optionSpy).toHaveBeenCalledWith('internal', expect.objectContaining({ type: 'boolean', hidden: true }));
|
|
32
|
+
// Template creation flags
|
|
33
|
+
expect(optionSpy).toHaveBeenCalledWith('template-type', expect.objectContaining({
|
|
34
|
+
type: 'string',
|
|
35
|
+
choices: [...TEMPLATE_TYPES],
|
|
36
|
+
}));
|
|
37
|
+
// Module creation flags
|
|
38
|
+
expect(optionSpy).toHaveBeenCalledWith('module-label', expect.objectContaining({ type: 'string' }));
|
|
39
|
+
expect(optionSpy).toHaveBeenCalledWith('react-type', expect.objectContaining({ type: 'boolean' }));
|
|
40
|
+
expect(optionSpy).toHaveBeenCalledWith('content-types', expect.objectContaining({ type: 'string' }));
|
|
41
|
+
expect(optionSpy).toHaveBeenCalledWith('global', expect.objectContaining({ type: 'boolean' }));
|
|
42
|
+
expect(optionSpy).toHaveBeenCalledWith('available-for-new-content', expect.objectContaining({ type: 'boolean' }));
|
|
43
|
+
// Function creation flags
|
|
44
|
+
expect(optionSpy).toHaveBeenCalledWith('functions-folder', expect.objectContaining({ type: 'string' }));
|
|
45
|
+
expect(optionSpy).toHaveBeenCalledWith('filename', expect.objectContaining({ type: 'string' }));
|
|
46
|
+
expect(optionSpy).toHaveBeenCalledWith('endpoint-method', expect.objectContaining({
|
|
47
|
+
type: 'string',
|
|
48
|
+
choices: [...HTTP_METHODS],
|
|
49
|
+
}));
|
|
50
|
+
expect(optionSpy).toHaveBeenCalledWith('endpoint-path', expect.objectContaining({ type: 'string' }));
|
|
31
51
|
});
|
|
32
52
|
});
|
|
33
53
|
});
|
|
@@ -2,6 +2,7 @@ import yargs from 'yargs';
|
|
|
2
2
|
import testAccountCreateCommand from '../testAccount/create.js';
|
|
3
3
|
import testAccountCreateConfigCommand from '../testAccount/createConfig.js';
|
|
4
4
|
import testAccountDeleteCommand from '../testAccount/delete.js';
|
|
5
|
+
import testAccountImportDataCommand from '../testAccount/importData.js';
|
|
5
6
|
import testAccountCommands from '../testAccount.js';
|
|
6
7
|
vi.mock('../testAccount/create');
|
|
7
8
|
vi.mock('../testAccount/createConfig');
|
|
@@ -37,6 +38,7 @@ describe('commands/testAccount', () => {
|
|
|
37
38
|
testAccountCreateCommand,
|
|
38
39
|
testAccountCreateConfigCommand,
|
|
39
40
|
testAccountDeleteCommand,
|
|
41
|
+
testAccountImportDataCommand,
|
|
40
42
|
];
|
|
41
43
|
it('should demand the command takes one positional argument', () => {
|
|
42
44
|
testAccountCommands.builder(yargs);
|
|
@@ -10,6 +10,7 @@ vi.mock('@hubspot/local-dev-lib/config');
|
|
|
10
10
|
vi.mock('@hubspot/local-dev-lib/logger');
|
|
11
11
|
vi.mock('../../../lib/app/migrate');
|
|
12
12
|
vi.mock('../../../lib/app/migrate_legacy');
|
|
13
|
+
vi.mock('../../../lib/projects/config.js');
|
|
13
14
|
const mockYargs = yargs;
|
|
14
15
|
const mockedGetAccountConfig = getAccountConfig;
|
|
15
16
|
const mockedMigrateApp2023_2 = migrateApp2023_2;
|
|
@@ -5,8 +5,8 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
|
5
5
|
const functionAssetType = {
|
|
6
6
|
hidden: false,
|
|
7
7
|
dest: ({ name }) => name,
|
|
8
|
-
execute: async ({ dest }) => {
|
|
9
|
-
const functionDefinition = await createFunctionPrompt();
|
|
8
|
+
execute: async ({ dest, commandArgs }) => {
|
|
9
|
+
const functionDefinition = await createFunctionPrompt(commandArgs);
|
|
10
10
|
try {
|
|
11
11
|
await createFunction(functionDefinition, dest);
|
|
12
12
|
}
|
|
@@ -14,8 +14,8 @@ const moduleAssetType = {
|
|
|
14
14
|
}
|
|
15
15
|
return true;
|
|
16
16
|
},
|
|
17
|
-
execute: async ({ name, dest, getInternalVersion }) => {
|
|
18
|
-
const moduleDefinition = await createModulePrompt();
|
|
17
|
+
execute: async ({ name, dest, getInternalVersion, commandArgs }) => {
|
|
18
|
+
const moduleDefinition = await createModulePrompt(commandArgs);
|
|
19
19
|
try {
|
|
20
20
|
await createModule(moduleDefinition, name, dest, getInternalVersion);
|
|
21
21
|
}
|
|
@@ -14,8 +14,8 @@ const templateAssetType = {
|
|
|
14
14
|
}
|
|
15
15
|
return true;
|
|
16
16
|
},
|
|
17
|
-
execute: async ({ name, dest }) => {
|
|
18
|
-
const { templateType } = await createTemplatePrompt();
|
|
17
|
+
execute: async ({ name, dest, commandArgs }) => {
|
|
18
|
+
const { templateType } = await createTemplatePrompt(commandArgs);
|
|
19
19
|
try {
|
|
20
20
|
await createTemplate(name, dest, templateType);
|
|
21
21
|
}
|
package/commands/create.js
CHANGED
|
@@ -8,6 +8,7 @@ import { commands } from '../lang/en.js';
|
|
|
8
8
|
import { uiLogger } from '../lib/ui/logger.js';
|
|
9
9
|
import { makeYargsBuilder } from '../lib/yargsUtils.js';
|
|
10
10
|
import { EXIT_CODES } from '../lib/enums/exitCodes.js';
|
|
11
|
+
import { TEMPLATE_TYPES, HTTP_METHODS, CONTENT_TYPES } from '../types/Cms.js';
|
|
11
12
|
const SUPPORTED_ASSET_TYPES = Object.keys(assets)
|
|
12
13
|
.filter(t => !assets[t].hidden)
|
|
13
14
|
.join(', ');
|
|
@@ -73,6 +74,52 @@ function createBuilder(yargs) {
|
|
|
73
74
|
type: 'boolean',
|
|
74
75
|
hidden: true,
|
|
75
76
|
});
|
|
77
|
+
yargs.option('template-type', {
|
|
78
|
+
describe: commands.create.flags.templateType.describe,
|
|
79
|
+
type: 'string',
|
|
80
|
+
choices: [...TEMPLATE_TYPES],
|
|
81
|
+
});
|
|
82
|
+
yargs.option('module-label', {
|
|
83
|
+
describe: commands.create.flags.moduleLabel.describe,
|
|
84
|
+
type: 'string',
|
|
85
|
+
});
|
|
86
|
+
yargs.option('react-type', {
|
|
87
|
+
describe: commands.create.flags.reactType.describe,
|
|
88
|
+
type: 'boolean',
|
|
89
|
+
default: false,
|
|
90
|
+
});
|
|
91
|
+
yargs.option('content-types', {
|
|
92
|
+
describe: commands.create.flags.contentTypes.describe(CONTENT_TYPES),
|
|
93
|
+
type: 'string',
|
|
94
|
+
});
|
|
95
|
+
yargs.option('global', {
|
|
96
|
+
describe: commands.create.flags.global.describe,
|
|
97
|
+
type: 'boolean',
|
|
98
|
+
default: false,
|
|
99
|
+
});
|
|
100
|
+
yargs.option('available-for-new-content', {
|
|
101
|
+
describe: commands.create.flags.availableForNewContent.describe,
|
|
102
|
+
type: 'boolean',
|
|
103
|
+
default: true,
|
|
104
|
+
});
|
|
105
|
+
yargs.option('functions-folder', {
|
|
106
|
+
describe: commands.create.flags.functionsFolder.describe,
|
|
107
|
+
type: 'string',
|
|
108
|
+
});
|
|
109
|
+
yargs.option('filename', {
|
|
110
|
+
describe: commands.create.flags.filename.describe,
|
|
111
|
+
type: 'string',
|
|
112
|
+
});
|
|
113
|
+
yargs.option('endpoint-method', {
|
|
114
|
+
describe: commands.create.flags.endpointMethod.describe,
|
|
115
|
+
type: 'string',
|
|
116
|
+
choices: [...HTTP_METHODS],
|
|
117
|
+
default: 'GET',
|
|
118
|
+
});
|
|
119
|
+
yargs.option('endpoint-path', {
|
|
120
|
+
describe: commands.create.flags.endpointPath.describe,
|
|
121
|
+
type: 'string',
|
|
122
|
+
});
|
|
76
123
|
return yargs;
|
|
77
124
|
}
|
|
78
125
|
const builder = makeYargsBuilder(createBuilder, command, describe, {
|
package/commands/getStarted.js
CHANGED
|
@@ -4,12 +4,12 @@ import open from 'open';
|
|
|
4
4
|
import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
5
5
|
import { cloneGithubRepo } from '@hubspot/local-dev-lib/github';
|
|
6
6
|
import { commands } from '../lang/en.js';
|
|
7
|
-
import { trackCommandUsage } from '../lib/usageTracking.js';
|
|
7
|
+
import { trackCommandMetadataUsage, trackCommandUsage, } from '../lib/usageTracking.js';
|
|
8
8
|
import { EXIT_CODES } from '../lib/enums/exitCodes.js';
|
|
9
9
|
import { makeYargsBuilder } from '../lib/yargsUtils.js';
|
|
10
10
|
import { promptUser } from '../lib/prompts/promptUtils.js';
|
|
11
11
|
import { projectNameAndDestPrompt } from '../lib/prompts/projectNameAndDestPrompt.js';
|
|
12
|
-
import { uiFeatureHighlight, uiInfoSection } from '../lib/ui/index.js';
|
|
12
|
+
import { uiAccountDescription, uiFeatureHighlight, uiInfoSection, } from '../lib/ui/index.js';
|
|
13
13
|
import { uiLogger } from '../lib/ui/logger.js';
|
|
14
14
|
import { debugError, logError } from '../lib/errorHandlers/index.js';
|
|
15
15
|
import { handleProjectUpload } from '../lib/projects/upload.js';
|
|
@@ -27,9 +27,9 @@ export const describe = undefined;
|
|
|
27
27
|
async function handler(args) {
|
|
28
28
|
const { derivedAccountId } = args;
|
|
29
29
|
const env = getEnv(derivedAccountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD;
|
|
30
|
+
await trackCommandUsage('get-started', {}, derivedAccountId);
|
|
30
31
|
// TODO: Put this in constants.ts once we have a defined place for the template before INBOUND
|
|
31
32
|
const templateSource = 'robrown-hubspot/hubspot-project-components-ua-app-objects-beta';
|
|
32
|
-
trackCommandUsage('get-started', {}, derivedAccountId);
|
|
33
33
|
uiInfoSection(commands.getStarted.startTitle, () => {
|
|
34
34
|
uiLogger.log(commands.getStarted.startDescription);
|
|
35
35
|
});
|
|
@@ -51,6 +51,8 @@ async function handler(args) {
|
|
|
51
51
|
default: GET_STARTED_OPTIONS.APP,
|
|
52
52
|
},
|
|
53
53
|
]);
|
|
54
|
+
// Track user's initial choice
|
|
55
|
+
await trackCommandMetadataUsage('get-started', { step: 'select-option', type: selectedOption }, derivedAccountId);
|
|
54
56
|
if (selectedOption === GET_STARTED_OPTIONS.CMS) {
|
|
55
57
|
uiLogger.log(' ');
|
|
56
58
|
uiLogger.log(commands.getStarted.designManager);
|
|
@@ -63,6 +65,11 @@ async function handler(args) {
|
|
|
63
65
|
message: commands.getStarted.openDesignManagerPrompt,
|
|
64
66
|
},
|
|
65
67
|
]);
|
|
68
|
+
// Track Design Manager browser action
|
|
69
|
+
await trackCommandMetadataUsage('get-started', {
|
|
70
|
+
step: 'open-design-manager',
|
|
71
|
+
type: shouldOpen ? 'opened' : 'declined',
|
|
72
|
+
}, derivedAccountId);
|
|
66
73
|
if (shouldOpen) {
|
|
67
74
|
uiLogger.log('');
|
|
68
75
|
openLink(derivedAccountId, 'design-manager');
|
|
@@ -88,6 +95,11 @@ async function handler(args) {
|
|
|
88
95
|
if (existingProjectConfig &&
|
|
89
96
|
existingProjectDir &&
|
|
90
97
|
projectDest.startsWith(existingProjectDir)) {
|
|
98
|
+
// Track nested project error
|
|
99
|
+
await trackCommandMetadataUsage('get-started', {
|
|
100
|
+
successful: false,
|
|
101
|
+
step: 'project-creation',
|
|
102
|
+
}, derivedAccountId);
|
|
91
103
|
uiLogger.log(' ');
|
|
92
104
|
uiLogger.error(commands.project.create.errors.cannotNestProjects(existingProjectDir));
|
|
93
105
|
process.exit(EXIT_CODES.ERROR);
|
|
@@ -101,8 +113,16 @@ async function handler(args) {
|
|
|
101
113
|
tag: latestRepoReleaseTag,
|
|
102
114
|
hideLogs: true,
|
|
103
115
|
});
|
|
116
|
+
await trackCommandMetadataUsage('get-started', {
|
|
117
|
+
successful: true,
|
|
118
|
+
step: 'github-clone',
|
|
119
|
+
}, derivedAccountId);
|
|
104
120
|
}
|
|
105
121
|
catch (err) {
|
|
122
|
+
await trackCommandMetadataUsage('get-started', {
|
|
123
|
+
successful: false,
|
|
124
|
+
step: 'github-clone',
|
|
125
|
+
}, derivedAccountId);
|
|
106
126
|
debugError(err);
|
|
107
127
|
uiLogger.log(' ');
|
|
108
128
|
uiLogger.error(commands.project.create.errors.failedToDownloadProject);
|
|
@@ -121,6 +141,11 @@ async function handler(args) {
|
|
|
121
141
|
uiLogger.log(' ');
|
|
122
142
|
uiLogger.log(commands.getStarted.prompts.projectCreated.description);
|
|
123
143
|
uiLogger.log(' ');
|
|
144
|
+
// Track successful project creation
|
|
145
|
+
await trackCommandMetadataUsage('get-started', {
|
|
146
|
+
successful: true,
|
|
147
|
+
step: 'project-creation',
|
|
148
|
+
}, derivedAccountId);
|
|
124
149
|
// 5. Install dependencies
|
|
125
150
|
const installLocations = await getProjectPackageJsonLocations(projectDest);
|
|
126
151
|
try {
|
|
@@ -138,19 +163,30 @@ async function handler(args) {
|
|
|
138
163
|
uiLogger.log(' ');
|
|
139
164
|
}
|
|
140
165
|
// 6. Ask user if they want to upload the project
|
|
166
|
+
const accountName = uiAccountDescription(derivedAccountId);
|
|
141
167
|
const { shouldUpload } = await promptUser([
|
|
142
168
|
{
|
|
143
169
|
type: 'confirm',
|
|
144
170
|
name: 'shouldUpload',
|
|
145
|
-
message: commands.getStarted.prompts.uploadProject,
|
|
171
|
+
message: commands.getStarted.prompts.uploadProject(accountName),
|
|
146
172
|
default: true,
|
|
147
173
|
},
|
|
148
174
|
]);
|
|
175
|
+
// Track upload decision
|
|
176
|
+
await trackCommandMetadataUsage('get-started', {
|
|
177
|
+
step: 'upload-decision',
|
|
178
|
+
type: shouldUpload ? 'upload' : 'skip',
|
|
179
|
+
}, derivedAccountId);
|
|
149
180
|
if (shouldUpload) {
|
|
150
181
|
try {
|
|
151
182
|
// Get the project config for the newly created project
|
|
152
183
|
const { projectConfig: newProjectConfig, projectDir: newProjectDir } = await getProjectConfig(projectDest);
|
|
153
184
|
if (!newProjectConfig || !newProjectDir) {
|
|
185
|
+
// Track config file not found error
|
|
186
|
+
await trackCommandMetadataUsage('get-started', {
|
|
187
|
+
successful: false,
|
|
188
|
+
step: 'config-file-not-found',
|
|
189
|
+
}, derivedAccountId);
|
|
154
190
|
uiLogger.log(' ');
|
|
155
191
|
uiLogger.error(commands.getStarted.errors.configFileNotFound);
|
|
156
192
|
process.exit(EXIT_CODES.ERROR);
|
|
@@ -172,11 +208,22 @@ async function handler(args) {
|
|
|
172
208
|
skipValidation: false,
|
|
173
209
|
});
|
|
174
210
|
if (uploadError) {
|
|
211
|
+
// Track upload failure
|
|
212
|
+
await trackCommandMetadataUsage('get-started', {
|
|
213
|
+
successful: false,
|
|
214
|
+
step: 'upload',
|
|
215
|
+
}, derivedAccountId);
|
|
175
216
|
uiLogger.log(' ');
|
|
176
217
|
uiLogger.error(commands.getStarted.errors.uploadFailed);
|
|
177
218
|
debugError(uploadError);
|
|
178
219
|
}
|
|
179
220
|
else if (result) {
|
|
221
|
+
// Track successful upload completion
|
|
222
|
+
await trackCommandMetadataUsage('get-started', {
|
|
223
|
+
successful: true,
|
|
224
|
+
step: 'upload',
|
|
225
|
+
}, derivedAccountId);
|
|
226
|
+
uiLogger.log(' ');
|
|
180
227
|
uiLogger.success(commands.getStarted.logs.uploadSuccess);
|
|
181
228
|
const { data: { results }, } = await fetchPublicAppsForPortal(derivedAccountId);
|
|
182
229
|
const lastCreatedApp = results.sort((a, b) => b.createdAt - a.createdAt)[0];
|
|
@@ -191,6 +238,11 @@ async function handler(args) {
|
|
|
191
238
|
message: commands.getStarted.openInstallUrl,
|
|
192
239
|
},
|
|
193
240
|
]);
|
|
241
|
+
// Track Developer Overview browser action
|
|
242
|
+
await trackCommandMetadataUsage('get-started', {
|
|
243
|
+
step: 'open-distribution-page',
|
|
244
|
+
type: shouldOpenOverview ? 'opened' : 'declined',
|
|
245
|
+
}, derivedAccountId);
|
|
194
246
|
if (shouldOpenOverview) {
|
|
195
247
|
open(getStaticAuthAppInstallUrl({
|
|
196
248
|
targetAccountId: derivedAccountId,
|
|
@@ -206,6 +258,11 @@ async function handler(args) {
|
|
|
206
258
|
}
|
|
207
259
|
}
|
|
208
260
|
catch (err) {
|
|
261
|
+
// Track upload exception
|
|
262
|
+
await trackCommandMetadataUsage('get-started', {
|
|
263
|
+
successful: false,
|
|
264
|
+
step: 'upload',
|
|
265
|
+
}, derivedAccountId);
|
|
209
266
|
uiLogger.log(' ');
|
|
210
267
|
uiLogger.error(commands.getStarted.errors.uploadFailed);
|
|
211
268
|
debugError(err);
|
|
@@ -213,6 +270,11 @@ async function handler(args) {
|
|
|
213
270
|
}
|
|
214
271
|
}
|
|
215
272
|
}
|
|
273
|
+
// Track successful completion of get-started command
|
|
274
|
+
await trackCommandMetadataUsage('get-started', {
|
|
275
|
+
successful: true,
|
|
276
|
+
step: 'command-completed',
|
|
277
|
+
}, derivedAccountId);
|
|
216
278
|
process.exit(EXIT_CODES.SUCCESS);
|
|
217
279
|
}
|
|
218
280
|
function getStartedBuilder(yargs) {
|
package/commands/mcp/setup.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { CommonArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
2
|
interface MCPSetupArgs extends CommonArgs {
|
|
3
3
|
client?: string[];
|
|
4
|
-
addDocsSearch?: boolean;
|
|
5
4
|
}
|
|
6
5
|
declare const mcpSetupCommand: YargsCommandModule<unknown, MCPSetupArgs>;
|
|
7
6
|
export default mcpSetupCommand;
|
package/commands/mcp/setup.js
CHANGED
|
@@ -2,7 +2,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
|
2
2
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
3
3
|
import { commands } from '../../lang/en.js';
|
|
4
4
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
5
|
-
import { addMcpServerToConfig,
|
|
5
|
+
import { addMcpServerToConfig, supportedTools } from '../../lib/mcp/setup.js';
|
|
6
6
|
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
7
7
|
const command = ['setup', 'update'];
|
|
8
8
|
const describe = undefined; // Leave hidden for now
|
|
@@ -16,10 +16,7 @@ async function handler(args) {
|
|
|
16
16
|
}
|
|
17
17
|
trackCommandUsage('mcp-setup', {}, args.derivedAccountId);
|
|
18
18
|
try {
|
|
19
|
-
|
|
20
|
-
if (args.addDocsSearch) {
|
|
21
|
-
await addMintlifyMcpServer(derivedTargets);
|
|
22
|
-
}
|
|
19
|
+
await addMcpServerToConfig(args.client);
|
|
23
20
|
}
|
|
24
21
|
catch (e) {
|
|
25
22
|
process.exit(EXIT_CODES.ERROR);
|
|
@@ -27,15 +24,10 @@ async function handler(args) {
|
|
|
27
24
|
process.exit(EXIT_CODES.SUCCESS);
|
|
28
25
|
}
|
|
29
26
|
function setupBuilder(yargs) {
|
|
30
|
-
yargs
|
|
31
|
-
.option('client', {
|
|
27
|
+
yargs.option('client', {
|
|
32
28
|
describe: commands.mcp.setup.args.client,
|
|
33
29
|
type: 'array',
|
|
34
30
|
choices: [...supportedTools.map(tool => tool.value)],
|
|
35
|
-
})
|
|
36
|
-
.option('add-docs-search', {
|
|
37
|
-
type: 'boolean',
|
|
38
|
-
hidden: true,
|
|
39
31
|
});
|
|
40
32
|
return yargs;
|
|
41
33
|
}
|
|
@@ -27,14 +27,71 @@ describe('commands/project/create', () => {
|
|
|
27
27
|
it('should define project creation options', () => {
|
|
28
28
|
const optionsSpy = vi.spyOn(yargsMock, 'options');
|
|
29
29
|
const exampleSpy = vi.spyOn(yargsMock, 'example');
|
|
30
|
+
const conflictsSpy = vi.spyOn(yargsMock, 'conflicts');
|
|
30
31
|
projectCreateCommand.builder(yargsMock);
|
|
31
32
|
expect(optionsSpy).toHaveBeenCalledWith(expect.objectContaining({
|
|
32
33
|
name: expect.any(Object),
|
|
33
34
|
dest: expect.any(Object),
|
|
34
35
|
template: expect.any(Object),
|
|
35
36
|
'template-source': expect.any(Object),
|
|
37
|
+
'platform-version': expect.any(Object),
|
|
38
|
+
'project-base': expect.any(Object),
|
|
39
|
+
distribution: expect.any(Object),
|
|
40
|
+
auth: expect.any(Object),
|
|
41
|
+
features: expect.any(Object),
|
|
36
42
|
}));
|
|
43
|
+
expect(conflictsSpy).toHaveBeenCalledWith('template', 'features');
|
|
37
44
|
expect(exampleSpy).toHaveBeenCalled();
|
|
38
45
|
});
|
|
46
|
+
it('should define platform version option with correct choices', () => {
|
|
47
|
+
const optionsSpy = vi.spyOn(yargsMock, 'options');
|
|
48
|
+
projectCreateCommand.builder(yargsMock);
|
|
49
|
+
const optionsCall = optionsSpy.mock.calls[0][0];
|
|
50
|
+
expect(optionsCall['platform-version']).toEqual(expect.objectContaining({
|
|
51
|
+
hidden: true,
|
|
52
|
+
type: 'string',
|
|
53
|
+
choices: ['2023.2', '2025.1', '2025.2'],
|
|
54
|
+
default: '2023.2',
|
|
55
|
+
}));
|
|
56
|
+
});
|
|
57
|
+
it('should define project base option with correct choices', () => {
|
|
58
|
+
const optionsSpy = vi.spyOn(yargsMock, 'options');
|
|
59
|
+
projectCreateCommand.builder(yargsMock);
|
|
60
|
+
const optionsCall = optionsSpy.mock.calls[0][0];
|
|
61
|
+
expect(optionsCall['project-base']).toEqual(expect.objectContaining({
|
|
62
|
+
hidden: true,
|
|
63
|
+
type: 'string',
|
|
64
|
+
choices: ['empty', 'app'],
|
|
65
|
+
}));
|
|
66
|
+
});
|
|
67
|
+
it('should define distribution option with correct choices', () => {
|
|
68
|
+
const optionsSpy = vi.spyOn(yargsMock, 'options');
|
|
69
|
+
projectCreateCommand.builder(yargsMock);
|
|
70
|
+
const optionsCall = optionsSpy.mock.calls[0][0];
|
|
71
|
+
expect(optionsCall.distribution).toEqual(expect.objectContaining({
|
|
72
|
+
hidden: true,
|
|
73
|
+
type: 'string',
|
|
74
|
+
choices: ['private', 'marketplace'],
|
|
75
|
+
}));
|
|
76
|
+
});
|
|
77
|
+
it('should define auth option with correct choices', () => {
|
|
78
|
+
const optionsSpy = vi.spyOn(yargsMock, 'options');
|
|
79
|
+
projectCreateCommand.builder(yargsMock);
|
|
80
|
+
const optionsCall = optionsSpy.mock.calls[0][0];
|
|
81
|
+
expect(optionsCall.auth).toEqual(expect.objectContaining({
|
|
82
|
+
hidden: true,
|
|
83
|
+
type: 'string',
|
|
84
|
+
choices: ['oauth', 'static'],
|
|
85
|
+
}));
|
|
86
|
+
});
|
|
87
|
+
it('should define features option as array', () => {
|
|
88
|
+
const optionsSpy = vi.spyOn(yargsMock, 'options');
|
|
89
|
+
projectCreateCommand.builder(yargsMock);
|
|
90
|
+
const optionsCall = optionsSpy.mock.calls[0][0];
|
|
91
|
+
expect(optionsCall.features).toEqual(expect.objectContaining({
|
|
92
|
+
hidden: true,
|
|
93
|
+
type: 'array',
|
|
94
|
+
}));
|
|
95
|
+
});
|
|
39
96
|
});
|
|
40
97
|
});
|
|
@@ -5,7 +5,8 @@ import { getConfigAccounts, getAccountConfig, } from '@hubspot/local-dev-lib/con
|
|
|
5
5
|
import { getValidEnv } from '@hubspot/local-dev-lib/environment';
|
|
6
6
|
import { logError } from '../../../lib/errorHandlers/index.js';
|
|
7
7
|
import { ensureProjectExists } from '../../../lib/projects/ensureProjectExists.js';
|
|
8
|
-
import { createInitialBuildForNewProject, createNewProjectForLocalDev,
|
|
8
|
+
import { createInitialBuildForNewProject, createNewProjectForLocalDev, } from '../../../lib/projects/localDev/helpers/project.js';
|
|
9
|
+
import { useExistingDevTestAccount, createDeveloperTestAccountForLocalDev, selectAccountTypePrompt, } from '../../../lib/projects/localDev/helpers/account.js';
|
|
9
10
|
import { selectDeveloperTestTargetAccountPrompt, selectSandboxTargetAccountPrompt, } from '../../../lib/prompts/projectDevTargetAccountPrompt.js';
|
|
10
11
|
import SpinniesManager from '../../../lib/ui/SpinniesManager.js';
|
|
11
12
|
import LocalDevProcess from '../../../lib/projects/localDev/LocalDevProcess.js';
|
|
@@ -34,7 +35,8 @@ vi.mock('@hubspot/local-dev-lib/config');
|
|
|
34
35
|
vi.mock('@hubspot/local-dev-lib/environment');
|
|
35
36
|
vi.mock('../../../lib/errorHandlers');
|
|
36
37
|
vi.mock('../../../lib/projects/ensureProjectExists');
|
|
37
|
-
vi.mock('../../../lib/projects/localDev/helpers');
|
|
38
|
+
vi.mock('../../../lib/projects/localDev/helpers/project');
|
|
39
|
+
vi.mock('../../../lib/projects/localDev/helpers/account');
|
|
38
40
|
vi.mock('../../../lib/prompts/projectDevTargetAccountPrompt');
|
|
39
41
|
vi.mock('../../../lib/ui/SpinniesManager');
|
|
40
42
|
vi.mock('../../../lib/projects/localDev/LocalDevProcess');
|
|
@@ -322,31 +324,10 @@ describe('unifiedProjectDevFlow', () => {
|
|
|
322
324
|
});
|
|
323
325
|
expect(createNewProjectForLocalDev).not.toHaveBeenCalled();
|
|
324
326
|
expect(LocalDevProcess).toHaveBeenCalledWith(expect.objectContaining({
|
|
325
|
-
deployedBuild: mockProject.deployedBuild,
|
|
326
327
|
projectId: mockProject.id,
|
|
327
328
|
projectName: mockProject.name,
|
|
328
329
|
}));
|
|
329
330
|
});
|
|
330
|
-
it('should detect GitHub linked projects', async () => {
|
|
331
|
-
const githubLinkedProject = {
|
|
332
|
-
...mockProject,
|
|
333
|
-
sourceIntegration: { source: 'GITHUB' },
|
|
334
|
-
};
|
|
335
|
-
ensureProjectExists.mockResolvedValue({
|
|
336
|
-
projectExists: true,
|
|
337
|
-
project: githubLinkedProject,
|
|
338
|
-
});
|
|
339
|
-
await unifiedProjectDevFlow({
|
|
340
|
-
args: mockArgs,
|
|
341
|
-
targetProjectAccountId: mockTargetProjectAccountId,
|
|
342
|
-
providedTargetTestingAccountId: mockProvidedTargetTestingAccountId,
|
|
343
|
-
projectConfig: mockProjectConfig,
|
|
344
|
-
projectDir: mockProjectDir,
|
|
345
|
-
});
|
|
346
|
-
expect(LocalDevProcess).toHaveBeenCalledWith(expect.objectContaining({
|
|
347
|
-
isGithubLinked: true,
|
|
348
|
-
}));
|
|
349
|
-
});
|
|
350
331
|
});
|
|
351
332
|
describe('local dev process setup', () => {
|
|
352
333
|
it('should initialize LocalDevProcess with correct parameters', async () => {
|
|
@@ -360,8 +341,6 @@ describe('unifiedProjectDevFlow', () => {
|
|
|
360
341
|
expect(LocalDevProcess).toHaveBeenCalledWith({
|
|
361
342
|
initialProjectNodes: mockProjectNodes,
|
|
362
343
|
debug: mockArgs.debug,
|
|
363
|
-
deployedBuild: mockProject.deployedBuild,
|
|
364
|
-
isGithubLinked: false,
|
|
365
344
|
profile: mockArgs.profile,
|
|
366
345
|
targetProjectAccountId: mockTargetProjectAccountId,
|
|
367
346
|
targetTestingAccountId: mockProvidedTargetTestingAccountId,
|
|
@@ -401,17 +380,26 @@ describe('unifiedProjectDevFlow', () => {
|
|
|
401
380
|
beforeEach(() => {
|
|
402
381
|
isTestAccountOrSandbox.mockReturnValue(false);
|
|
403
382
|
});
|
|
404
|
-
it('should
|
|
405
|
-
|
|
383
|
+
it('should log info message when default account is a sandbox or test account', async () => {
|
|
384
|
+
isTestAccountOrSandbox.mockReturnValue(true);
|
|
385
|
+
await unifiedProjectDevFlow({
|
|
386
|
+
args: mockArgs,
|
|
387
|
+
targetProjectAccountId: mockTargetProjectAccountId,
|
|
388
|
+
projectConfig: mockProjectConfig,
|
|
389
|
+
projectDir: mockProjectDir,
|
|
390
|
+
});
|
|
391
|
+
expect(uiLogger.log).toHaveBeenCalledWith(commands.project.dev.logs.defaultSandboxOrDevTestTestingAccountExplanation(mockTargetProjectAccountId));
|
|
392
|
+
});
|
|
393
|
+
it('should log info message when testingAccount flag is provided', async () => {
|
|
394
|
+
const providedTestingAccountId = 999;
|
|
406
395
|
await unifiedProjectDevFlow({
|
|
407
396
|
args: mockArgs,
|
|
408
397
|
targetProjectAccountId: mockTargetProjectAccountId,
|
|
398
|
+
providedTargetTestingAccountId: providedTestingAccountId,
|
|
409
399
|
projectConfig: mockProjectConfig,
|
|
410
400
|
projectDir: mockProjectDir,
|
|
411
401
|
});
|
|
412
|
-
expect(
|
|
413
|
-
expect(uiLogger.log).toHaveBeenCalledWith(commands.project.dev.logs.accountTypeInformation);
|
|
414
|
-
expect(uiLogger.log).toHaveBeenCalledWith(commands.project.dev.logs.learnMoreMessage);
|
|
402
|
+
expect(uiLogger.log).toHaveBeenCalledWith(commands.project.dev.logs.testingAccountFlagExplanation(providedTestingAccountId));
|
|
415
403
|
});
|
|
416
404
|
});
|
|
417
405
|
});
|