@hubspot/cli 7.9.0-experimental.0 → 7.9.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/account/__tests__/rename.test.js +42 -0
- 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 +13 -18
- package/commands/account/remove.js +23 -22
- package/commands/account/removeOverride.js +6 -6
- package/commands/account/rename.d.ts +1 -1
- package/commands/account/rename.js +6 -3
- 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/config/set.js +1 -2
- package/commands/customObject/createSchema.js +2 -3
- package/commands/customObject/updateSchema.js +2 -3
- package/commands/getStarted.js +10 -5
- package/commands/hubdb/__tests__/list.test.js +1 -0
- package/commands/hubdb/list.js +2 -2
- package/commands/hubdb.d.ts +1 -1
- 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__/logs.test.js +4 -0
- package/commands/project/__tests__/validate.test.js +2 -2
- package/commands/project/cloneApp.js +2 -2
- package/commands/project/deploy.js +2 -2
- package/commands/project/dev/deprecatedFlow.js +4 -5
- package/commands/project/dev/index.js +14 -4
- package/commands/project/dev/unifiedFlow.js +4 -5
- package/commands/project/listBuilds.js +7 -1
- package/commands/project/logs.js +2 -3
- package/commands/project/profile/add.js +6 -7
- package/commands/project/profile/delete.js +2 -2
- package/commands/project/upload.js +9 -3
- package/commands/project/validate.js +9 -3
- package/commands/project/watch.js +7 -2
- 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/__tests__/create.test.js +68 -0
- package/commands/testAccount/create.d.ts +8 -0
- package/commands/testAccount/create.js +134 -44
- package/commands/testAccount/delete.js +9 -8
- package/commands/testAccount/importData.d.ts +1 -1
- package/lang/en.d.ts +3204 -3205
- package/lang/en.js +33 -9
- 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__/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/constants.d.ts +1 -0
- package/lib/constants.js +6 -0
- 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/mcp/__tests__/setup.test.js +127 -0
- package/lib/mcp/setup.d.ts +4 -12
- package/lib/mcp/setup.js +34 -1
- package/lib/middleware/__test__/commandTargetingUtils.test.js +3 -3
- package/lib/middleware/__test__/configMiddleware.test.js +23 -22
- package/lib/middleware/__test__/gitMiddleware.test.js +9 -7
- package/lib/middleware/autoUpdateMiddleware.d.ts +3 -1
- package/lib/middleware/autoUpdateMiddleware.js +10 -2
- package/lib/middleware/commandTargetingUtils.js +2 -2
- package/lib/middleware/configMiddleware.d.ts +6 -1
- package/lib/middleware/configMiddleware.js +36 -15
- package/lib/middleware/gitMiddleware.js +8 -4
- package/lib/oauth.d.ts +2 -2
- package/lib/oauth.js +8 -10
- 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__/components.test.js +148 -24
- package/lib/projects/__tests__/deploy.test.js +1 -0
- package/lib/projects/__tests__/projects.test.js +13 -42
- package/lib/projects/components.js +76 -20
- package/lib/projects/config.js +5 -9
- 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/urls.js +5 -6
- package/lib/prompts/__tests__/createDeveloperTestAccountConfigPrompt.test.d.ts +1 -0
- package/lib/prompts/__tests__/createDeveloperTestAccountConfigPrompt.test.js +153 -0
- 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/createDeveloperTestAccountConfigPrompt.d.ts +5 -0
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +76 -66
- 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 +8 -2
- package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +4 -4
- package/mcp-server/tools/cms/HsCreateModuleTool.js +8 -2
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +8 -2
- package/mcp-server/tools/cms/HsFunctionLogsTool.d.ts +4 -4
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +6 -2
- package/mcp-server/tools/cms/HsListFunctionsTool.js +5 -1
- package/mcp-server/tools/cms/HsListTool.js +5 -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.d.ts +1 -1
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +9 -3
- package/mcp-server/tools/project/CreateProjectTool.js +8 -2
- package/mcp-server/tools/project/CreateTestAccountTool.d.ts +41 -0
- package/mcp-server/tools/project/CreateTestAccountTool.js +150 -0
- package/mcp-server/tools/project/DeployProjectTool.d.ts +1 -1
- package/mcp-server/tools/project/DeployProjectTool.js +8 -2
- package/mcp-server/tools/project/DocFetchTool.d.ts +1 -1
- package/mcp-server/tools/project/DocFetchTool.js +9 -5
- package/mcp-server/tools/project/DocsSearchTool.d.ts +1 -1
- package/mcp-server/tools/project/DocsSearchTool.js +12 -8
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +1 -1
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +11 -7
- package/mcp-server/tools/project/GetApplicationInfoTool.d.ts +1 -1
- package/mcp-server/tools/project/GetApplicationInfoTool.js +11 -7
- package/mcp-server/tools/project/GetBuildStatusTool.d.ts +26 -0
- package/mcp-server/tools/project/GetBuildStatusTool.js +164 -0
- package/mcp-server/tools/project/GetConfigValuesTool.d.ts +1 -1
- package/mcp-server/tools/project/GetConfigValuesTool.js +11 -7
- package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +1 -1
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +7 -3
- package/mcp-server/tools/project/UploadProjectTools.d.ts +9 -3
- package/mcp-server/tools/project/UploadProjectTools.js +51 -5
- package/mcp-server/tools/project/ValidateProjectTool.d.ts +1 -1
- package/mcp-server/tools/project/ValidateProjectTool.js +7 -3
- package/mcp-server/tools/project/__tests__/CreateTestAccountTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/CreateTestAccountTool.test.js +454 -0
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +5 -1
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +25 -13
- 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__/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/tools/project/__tests__/UploadProjectTools.test.js +56 -4
- package/mcp-server/utils/__tests__/content.test.js +21 -20
- package/mcp-server/utils/__tests__/feedbackTracking.test.js +33 -28
- 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 +8 -7
- 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/{mcp-server/utils/__tests__/cliConfig.test.d.ts → lib/mcp/__tests__/setup.test.d.ts} +0 -0
package/lib/projects/config.js
CHANGED
|
@@ -4,8 +4,8 @@ import findup from 'findup-sync';
|
|
|
4
4
|
import { getAbsoluteFilePath, getCwd } from '@hubspot/local-dev-lib/path';
|
|
5
5
|
import { PROJECT_CONFIG_FILE } from '../constants.js';
|
|
6
6
|
import { lib } from '../../lang/en.js';
|
|
7
|
-
import { EXIT_CODES } from '../enums/exitCodes.js';
|
|
8
7
|
import { uiLogger } from '../ui/logger.js';
|
|
8
|
+
import ProjectValidationError from '../errors/ProjectValidationError.js';
|
|
9
9
|
export function writeProjectConfig(configPath, config) {
|
|
10
10
|
try {
|
|
11
11
|
fs.ensureFileSync(configPath);
|
|
@@ -50,21 +50,17 @@ export async function getProjectConfig(dir) {
|
|
|
50
50
|
}
|
|
51
51
|
export function validateProjectConfig(projectConfig, projectDir) {
|
|
52
52
|
if (!projectConfig || !projectDir) {
|
|
53
|
-
|
|
54
|
-
return process.exit(EXIT_CODES.ERROR);
|
|
53
|
+
throw new ProjectValidationError(lib.projects.validateProjectConfig.configNotFound);
|
|
55
54
|
}
|
|
56
55
|
if (!projectConfig.name || !projectConfig.srcDir) {
|
|
57
|
-
|
|
58
|
-
return process.exit(EXIT_CODES.ERROR);
|
|
56
|
+
throw new ProjectValidationError(lib.projects.validateProjectConfig.configMissingFields);
|
|
59
57
|
}
|
|
60
58
|
const resolvedPath = path.resolve(projectDir, projectConfig.srcDir);
|
|
61
59
|
if (!resolvedPath.startsWith(projectDir)) {
|
|
62
60
|
const projectConfigFile = path.relative('.', path.join(projectDir, PROJECT_CONFIG_FILE));
|
|
63
|
-
|
|
64
|
-
return process.exit(EXIT_CODES.ERROR);
|
|
61
|
+
throw new ProjectValidationError(lib.projects.validateProjectConfig.srcOutsideProjectDir(projectConfigFile, projectConfig.srcDir));
|
|
65
62
|
}
|
|
66
63
|
if (!fs.existsSync(resolvedPath)) {
|
|
67
|
-
|
|
68
|
-
return process.exit(EXIT_CODES.ERROR);
|
|
64
|
+
throw new ProjectValidationError(lib.projects.validateProjectConfig.srcDirNotFound(projectConfig.srcDir, projectDir));
|
|
69
65
|
}
|
|
70
66
|
}
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import { calculateComponentTemplateChoices } from '../v2.js';
|
|
2
2
|
import { hasFeature } from '../../../hasFeature.js';
|
|
3
|
+
import { getConfigAccountById as __getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
4
|
+
const getConfigAccountById = __getConfigAccountById;
|
|
3
5
|
vi.mock('../../ui/logger.js');
|
|
4
6
|
vi.mock('@hubspot/local-dev-lib/api/github');
|
|
5
7
|
vi.mock('../../../hasFeature.js');
|
|
8
|
+
vi.mock('@hubspot/local-dev-lib/config');
|
|
6
9
|
const mockHasFeature = vi.mocked(hasFeature);
|
|
7
10
|
describe('lib/projects/create/v2', () => {
|
|
8
11
|
beforeEach(() => {
|
|
9
12
|
mockHasFeature.mockResolvedValue(true);
|
|
13
|
+
// Mock account config
|
|
14
|
+
getConfigAccountById.mockReturnValue({
|
|
15
|
+
accountId: 123,
|
|
16
|
+
name: 'Test Account',
|
|
17
|
+
authType: 'personalaccesskey',
|
|
18
|
+
personalAccessKey: 'test-key',
|
|
19
|
+
env: 'prod',
|
|
20
|
+
});
|
|
10
21
|
});
|
|
11
22
|
describe('calculateComponentTemplateChoices()', () => {
|
|
12
23
|
beforeEach(() => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fetchAppInstallationData } from '@hubspot/local-dev-lib/api/localDevAuth';
|
|
2
2
|
import { fetchAppMetadataByUid, fetchPublicAppProductionInstallCounts, installStaticAuthAppOnTestAccount, } from '@hubspot/local-dev-lib/api/appsDev';
|
|
3
|
-
import {
|
|
3
|
+
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
4
4
|
import { APP_AUTH_TYPES, APP_DISTRIBUTION_TYPES, APP_INSTALLATION_STATES, LOCAL_DEV_SERVER_MESSAGE_TYPES, } from '../../constants.js';
|
|
5
5
|
import { EXIT_CODES } from '../../enums/exitCodes.js';
|
|
6
6
|
import { isAppIRNode } from '../../projects/structure.js';
|
|
@@ -67,7 +67,7 @@ class AppDevModeInterface {
|
|
|
67
67
|
return (this.appNode?.config.auth.type.toLowerCase() === APP_AUTH_TYPES.OAUTH);
|
|
68
68
|
}
|
|
69
69
|
isAutomaticallyInstallable() {
|
|
70
|
-
const targetTestingAccount =
|
|
70
|
+
const targetTestingAccount = getConfigAccountById(this.localDevState.targetTestingAccountId);
|
|
71
71
|
if (!targetTestingAccount) {
|
|
72
72
|
return false;
|
|
73
73
|
}
|
|
@@ -2,7 +2,7 @@ import { logger } from '@hubspot/local-dev-lib/logger';
|
|
|
2
2
|
import { DevModeInterface as UIEDevModeInterface } from '@hubspot/ui-extensions-dev-server';
|
|
3
3
|
import { startPortManagerServer, stopPortManagerServer, requestPorts, } from '@hubspot/local-dev-lib/portManager';
|
|
4
4
|
import { getHubSpotApiOrigin, getHubSpotWebsiteOrigin, } from '@hubspot/local-dev-lib/urls';
|
|
5
|
-
import {
|
|
5
|
+
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
6
6
|
import { ComponentTypes, } from '../../../types/Projects.js';
|
|
7
7
|
import { lib } from '../../../lang/en.js';
|
|
8
8
|
import { uiLogger } from '../../ui/logger.js';
|
|
@@ -58,7 +58,7 @@ class DevServerManager_DEPRECATED {
|
|
|
58
58
|
async setup({ components, onUploadRequired, accountId, setActiveApp, }) {
|
|
59
59
|
this.componentsByType = this.arrangeComponentsByType(components);
|
|
60
60
|
let env;
|
|
61
|
-
const accountConfig =
|
|
61
|
+
const accountConfig = getConfigAccountById(accountId);
|
|
62
62
|
if (accountConfig) {
|
|
63
63
|
env = accountConfig.env;
|
|
64
64
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { hasLocalStateFlag } from '@hubspot/local-dev-lib/config';
|
|
2
|
+
import { getConfigDefaultAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { uiLogger } from '../../ui/logger.js';
|
|
4
4
|
import { uiLine, uiAccountDescription, uiCommandReference, } from '../../ui/index.js';
|
|
5
5
|
import { lib } from '../../../lang/en.js';
|
|
@@ -30,9 +30,9 @@ class LocalDevLogger {
|
|
|
30
30
|
uiLogger.error(langFunction(e instanceof Error ? e.message : ''));
|
|
31
31
|
}
|
|
32
32
|
getUploadCommand() {
|
|
33
|
-
const currentDefaultAccount =
|
|
33
|
+
const currentDefaultAccount = getConfigDefaultAccountIfExists();
|
|
34
34
|
return this.state.targetProjectAccountId !==
|
|
35
|
-
|
|
35
|
+
currentDefaultAccount?.accountId
|
|
36
36
|
? uiCommandReference(`hs project upload --account=${this.state.targetProjectAccountId}`)
|
|
37
37
|
: uiCommandReference('hs project upload');
|
|
38
38
|
}
|
|
@@ -3,7 +3,7 @@ import chokidar from 'chokidar';
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { fetchAppInstallationData } from '@hubspot/local-dev-lib/api/localDevAuth';
|
|
5
5
|
import { fetchPublicAppsForPortal, fetchPublicAppProductionInstallCounts, } from '@hubspot/local-dev-lib/api/appsDev';
|
|
6
|
-
import {
|
|
6
|
+
import { getConfigDefaultAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
7
7
|
import { PROJECT_CONFIG_FILE } from '../../constants.js';
|
|
8
8
|
import SpinniesManager from '../../ui/SpinniesManager.js';
|
|
9
9
|
import DevServerManager_DEPRECATED from './DevServerManager_DEPRECATED.js';
|
|
@@ -200,8 +200,8 @@ class LocalDevManager {
|
|
|
200
200
|
});
|
|
201
201
|
}
|
|
202
202
|
getUploadCommand() {
|
|
203
|
-
const currentDefaultAccount =
|
|
204
|
-
return this.targetProjectAccountId !==
|
|
203
|
+
const currentDefaultAccount = getConfigDefaultAccountIfExists();
|
|
204
|
+
return this.targetProjectAccountId !== currentDefaultAccount?.accountId
|
|
205
205
|
? uiCommandReference(`hs project upload --account=${this.targetProjectAccountId}`)
|
|
206
206
|
: uiCommandReference('hs project upload');
|
|
207
207
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HubSpotConfigAccount } from '@hubspot/local-dev-lib/types/Accounts';
|
|
2
2
|
import { Environment } from '@hubspot/local-dev-lib/types/Config';
|
|
3
3
|
import { DeveloperTestAccount } from '@hubspot/local-dev-lib/types/developerTestAccounts.js';
|
|
4
4
|
import { ProjectDevTargetAccountPromptResponse } from '../../../prompts/projectDevTargetAccountPrompt.js';
|
|
5
|
-
export declare function confirmDefaultAccountIsTarget(accountConfig:
|
|
6
|
-
export declare function checkIfDefaultAccountIsSupported(accountConfig:
|
|
7
|
-
export declare function checkIfParentAccountIsAuthed(accountConfig:
|
|
8
|
-
export declare function checkIfAccountFlagIsSupported(accountConfig:
|
|
9
|
-
export declare function suggestRecommendedNestedAccount(accounts:
|
|
10
|
-
export declare function createSandboxForLocalDev(accountId: number, accountConfig:
|
|
11
|
-
export declare function createDeveloperTestAccountForLocalDev(accountId: number, accountConfig:
|
|
5
|
+
export declare function confirmDefaultAccountIsTarget(accountConfig: HubSpotConfigAccount): Promise<void>;
|
|
6
|
+
export declare function checkIfDefaultAccountIsSupported(accountConfig: HubSpotConfigAccount, hasPublicApps: boolean): Promise<void>;
|
|
7
|
+
export declare function checkIfParentAccountIsAuthed(accountConfig: HubSpotConfigAccount): void;
|
|
8
|
+
export declare function checkIfAccountFlagIsSupported(accountConfig: HubSpotConfigAccount, hasPublicApps: boolean): void;
|
|
9
|
+
export declare function suggestRecommendedNestedAccount(accounts: HubSpotConfigAccount[], accountConfig: HubSpotConfigAccount, hasPublicApps: boolean): Promise<ProjectDevTargetAccountPromptResponse>;
|
|
10
|
+
export declare function createSandboxForLocalDev(accountId: number, accountConfig: HubSpotConfigAccount, env: Environment): Promise<number>;
|
|
11
|
+
export declare function createDeveloperTestAccountForLocalDev(accountId: number, accountConfig: HubSpotConfigAccount, env: Environment, useV2?: boolean): Promise<number>;
|
|
12
12
|
export declare function useExistingDevTestAccount(env: Environment, account: DeveloperTestAccount): Promise<void>;
|
|
13
|
-
export declare function hasSandboxes(account:
|
|
14
|
-
export declare function selectAccountTypePrompt(accountConfig:
|
|
13
|
+
export declare function hasSandboxes(account: HubSpotConfigAccount): Promise<boolean>;
|
|
14
|
+
export declare function selectAccountTypePrompt(accountConfig: HubSpotConfigAccount): Promise<string | null>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { HUBSPOT_ACCOUNT_TYPE_STRINGS } from '@hubspot/local-dev-lib/constants/config';
|
|
2
|
-
import {
|
|
3
|
-
import { getAccountIdentifier } from '@hubspot/local-dev-lib/config/getAccountIdentifier';
|
|
2
|
+
import { getConfigAccountById, getConfigAccountIfExists, } from '@hubspot/local-dev-lib/config';
|
|
4
3
|
import { HUBSPOT_ACCOUNT_TYPES } from '@hubspot/local-dev-lib/constants/config';
|
|
5
4
|
import { getHubSpotWebsiteOrigin } from '@hubspot/local-dev-lib/urls';
|
|
6
5
|
import { isMissingScopeError } from '@hubspot/local-dev-lib/errors/index';
|
|
@@ -60,8 +59,8 @@ export async function checkIfDefaultAccountIsSupported(accountConfig, hasPublicA
|
|
|
60
59
|
}
|
|
61
60
|
export function checkIfParentAccountIsAuthed(accountConfig) {
|
|
62
61
|
if (!accountConfig.parentAccountId ||
|
|
63
|
-
!
|
|
64
|
-
uiLogger.error(lib.localDevHelpers.account.checkIfParentAccountIsAuthed.notAuthedError(accountConfig.parentAccountId || '', uiAccountDescription(
|
|
62
|
+
!getConfigAccountIfExists(accountConfig.parentAccountId)?.accountId) {
|
|
63
|
+
uiLogger.error(lib.localDevHelpers.account.checkIfParentAccountIsAuthed.notAuthedError(accountConfig.parentAccountId || '', uiAccountDescription(accountConfig.accountId)));
|
|
65
64
|
process.exit(EXIT_CODES.SUCCESS);
|
|
66
65
|
}
|
|
67
66
|
}
|
|
@@ -122,11 +121,7 @@ export async function createSandboxForLocalDev(accountId, accountConfig, env) {
|
|
|
122
121
|
trackCommandMetadataUsage('sandbox-create', { step: 'project-dev' }, accountId);
|
|
123
122
|
const result = await buildSandbox(name, accountConfig, HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX, env);
|
|
124
123
|
const targetAccountId = result.sandbox.sandboxHubId;
|
|
125
|
-
const sandboxAccountConfig =
|
|
126
|
-
if (!sandboxAccountConfig) {
|
|
127
|
-
uiLogger.error(lib.sandbox.create.developer.failure.generic);
|
|
128
|
-
process.exit(EXIT_CODES.ERROR);
|
|
129
|
-
}
|
|
124
|
+
const sandboxAccountConfig = getConfigAccountById(result.sandbox.sandboxHubId);
|
|
130
125
|
const syncTasks = await getAvailableSyncTypes(accountConfig, sandboxAccountConfig);
|
|
131
126
|
// For v1 sandboxes, keep sync here. Once we migrate to v2, this will be handled by BE automatically
|
|
132
127
|
await syncSandbox(sandboxAccountConfig, accountConfig, env, syncTasks, true);
|
|
@@ -190,7 +185,7 @@ export async function useExistingDevTestAccount(env, account) {
|
|
|
190
185
|
uiLogger.success(lib.developerTestAccount.create.success.configFileUpdated(devTestAcctConfigName, PERSONAL_ACCESS_KEY_AUTH_METHOD.name));
|
|
191
186
|
}
|
|
192
187
|
export async function hasSandboxes(account) {
|
|
193
|
-
const accountId =
|
|
188
|
+
const accountId = account.accountId;
|
|
194
189
|
if (!accountId) {
|
|
195
190
|
return false;
|
|
196
191
|
}
|
|
@@ -206,7 +201,7 @@ export async function hasSandboxes(account) {
|
|
|
206
201
|
// Top level prompt to choose the type of account to test on
|
|
207
202
|
export async function selectAccountTypePrompt(accountConfig) {
|
|
208
203
|
const hasAccessToSandboxes = await hasSandboxes(accountConfig);
|
|
209
|
-
const accountId =
|
|
204
|
+
const accountId = accountConfig.accountId;
|
|
210
205
|
const result = await listPrompt(lib.localDevHelpers.account.selectAccountTypePrompt.message, {
|
|
211
206
|
choices: [
|
|
212
207
|
{
|
package/lib/projects/urls.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { getHubSpotWebsiteOrigin } from '@hubspot/local-dev-lib/urls';
|
|
2
|
-
import {
|
|
3
|
-
import { ENVIRONMENTS } from '@hubspot/local-dev-lib/constants/environments';
|
|
2
|
+
import { getConfigAccountEnvironment } from '@hubspot/local-dev-lib/config';
|
|
4
3
|
function getBaseUrl(accountId) {
|
|
5
|
-
return getHubSpotWebsiteOrigin(
|
|
4
|
+
return getHubSpotWebsiteOrigin(getConfigAccountEnvironment(accountId));
|
|
6
5
|
}
|
|
7
6
|
function getProjectHomeUrl(accountId) {
|
|
8
7
|
return `${getBaseUrl(accountId)}/developer-projects/${accountId}`;
|
|
9
8
|
}
|
|
10
9
|
export function getProjectComponentDistributionUrl(projectName, componentName, accountId) {
|
|
11
|
-
const baseUrl = getHubSpotWebsiteOrigin(
|
|
10
|
+
const baseUrl = getHubSpotWebsiteOrigin(getConfigAccountEnvironment(accountId));
|
|
12
11
|
return `${baseUrl}/developer-projects/${accountId}/project/${projectName}/component/${componentName}/distribution`;
|
|
13
12
|
}
|
|
14
13
|
export function getDeveloperOverviewUrl(accountId) {
|
|
15
|
-
const baseUrl = getHubSpotWebsiteOrigin(
|
|
14
|
+
const baseUrl = getHubSpotWebsiteOrigin(getConfigAccountEnvironment(accountId));
|
|
16
15
|
return `${baseUrl}/developer-overview/${accountId}`;
|
|
17
16
|
}
|
|
18
17
|
export function getProjectDetailUrl(projectName, accountId) {
|
|
@@ -38,6 +37,6 @@ export function getLocalDevUiUrl(accountId, showWelcomeScreen) {
|
|
|
38
37
|
return `${getBaseUrl(accountId)}/developer-projects-local-dev/${accountId}${showWelcomeScreen ? '?welcome' : ''}`;
|
|
39
38
|
}
|
|
40
39
|
export function getAccountHomeUrl(accountId) {
|
|
41
|
-
const baseUrl = getHubSpotWebsiteOrigin(
|
|
40
|
+
const baseUrl = getHubSpotWebsiteOrigin(getConfigAccountEnvironment(accountId));
|
|
42
41
|
return `${baseUrl}/home?portalId=${accountId}`;
|
|
43
42
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { createDeveloperTestAccountConfigPrompt } from '../createDeveloperTestAccountConfigPrompt.js';
|
|
3
|
+
import * as promptUtils from '../promptUtils.js';
|
|
4
|
+
vi.mock('../promptUtils.js');
|
|
5
|
+
describe('createDeveloperTestAccountConfigPrompt', () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
vi.clearAllMocks();
|
|
8
|
+
});
|
|
9
|
+
describe('with name and description provided via args', () => {
|
|
10
|
+
it('should skip name and description prompts when provided', async () => {
|
|
11
|
+
const mockPromptUser = vi.mocked(promptUtils.promptUser);
|
|
12
|
+
mockPromptUser.mockResolvedValueOnce({}); // name/description prompts skipped
|
|
13
|
+
mockPromptUser.mockResolvedValueOnce({
|
|
14
|
+
useDefaultAccountLevels: 'default',
|
|
15
|
+
}); // tier selection
|
|
16
|
+
const result = await createDeveloperTestAccountConfigPrompt({
|
|
17
|
+
name: 'TestAccount',
|
|
18
|
+
description: 'Test description',
|
|
19
|
+
});
|
|
20
|
+
expect(result).toEqual({
|
|
21
|
+
accountName: 'TestAccount',
|
|
22
|
+
description: 'Test description',
|
|
23
|
+
marketingLevel: 'ENTERPRISE',
|
|
24
|
+
opsLevel: 'ENTERPRISE',
|
|
25
|
+
serviceLevel: 'ENTERPRISE',
|
|
26
|
+
salesLevel: 'ENTERPRISE',
|
|
27
|
+
contentLevel: 'ENTERPRISE',
|
|
28
|
+
});
|
|
29
|
+
expect(mockPromptUser).toHaveBeenCalledTimes(2);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe('with tier flags provided', () => {
|
|
33
|
+
it('should skip tier prompts and use provided values with defaults', async () => {
|
|
34
|
+
const mockPromptUser = vi.mocked(promptUtils.promptUser);
|
|
35
|
+
mockPromptUser.mockResolvedValueOnce({}); // name/description prompts skipped
|
|
36
|
+
const result = await createDeveloperTestAccountConfigPrompt({
|
|
37
|
+
name: 'TestAccount',
|
|
38
|
+
description: 'Test',
|
|
39
|
+
marketingLevel: 'PROFESSIONAL',
|
|
40
|
+
salesLevel: 'STARTER',
|
|
41
|
+
});
|
|
42
|
+
expect(result).toEqual({
|
|
43
|
+
accountName: 'TestAccount',
|
|
44
|
+
description: 'Test',
|
|
45
|
+
marketingLevel: 'PROFESSIONAL',
|
|
46
|
+
opsLevel: 'ENTERPRISE',
|
|
47
|
+
serviceLevel: 'ENTERPRISE',
|
|
48
|
+
salesLevel: 'STARTER',
|
|
49
|
+
contentLevel: 'ENTERPRISE',
|
|
50
|
+
});
|
|
51
|
+
// Should only call promptUser once (for name/description which are skipped)
|
|
52
|
+
expect(mockPromptUser).toHaveBeenCalledTimes(1);
|
|
53
|
+
});
|
|
54
|
+
it('should default unprovided tiers to ENTERPRISE', async () => {
|
|
55
|
+
const mockPromptUser = vi.mocked(promptUtils.promptUser);
|
|
56
|
+
mockPromptUser.mockResolvedValueOnce({
|
|
57
|
+
description: 'Test',
|
|
58
|
+
}); // description prompt (name provided via args, description not provided)
|
|
59
|
+
const result = await createDeveloperTestAccountConfigPrompt({
|
|
60
|
+
name: 'TestAccount',
|
|
61
|
+
contentLevel: 'FREE',
|
|
62
|
+
});
|
|
63
|
+
expect(result).toEqual({
|
|
64
|
+
accountName: 'TestAccount',
|
|
65
|
+
description: 'Test',
|
|
66
|
+
marketingLevel: 'ENTERPRISE',
|
|
67
|
+
opsLevel: 'ENTERPRISE',
|
|
68
|
+
serviceLevel: 'ENTERPRISE',
|
|
69
|
+
salesLevel: 'ENTERPRISE',
|
|
70
|
+
contentLevel: 'FREE',
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('with no flags provided', () => {
|
|
75
|
+
it('should prompt for name, description, and tier selection', async () => {
|
|
76
|
+
const mockPromptUser = vi.mocked(promptUtils.promptUser);
|
|
77
|
+
// First call: name/description prompts
|
|
78
|
+
mockPromptUser.mockResolvedValueOnce({
|
|
79
|
+
accountName: 'PromptedAccount',
|
|
80
|
+
description: 'Prompted description',
|
|
81
|
+
});
|
|
82
|
+
// Second call: tier selection
|
|
83
|
+
mockPromptUser.mockResolvedValueOnce({
|
|
84
|
+
useDefaultAccountLevels: 'default',
|
|
85
|
+
});
|
|
86
|
+
const result = await createDeveloperTestAccountConfigPrompt({});
|
|
87
|
+
expect(result).toEqual({
|
|
88
|
+
accountName: 'PromptedAccount',
|
|
89
|
+
description: 'Prompted description',
|
|
90
|
+
marketingLevel: 'ENTERPRISE',
|
|
91
|
+
opsLevel: 'ENTERPRISE',
|
|
92
|
+
serviceLevel: 'ENTERPRISE',
|
|
93
|
+
salesLevel: 'ENTERPRISE',
|
|
94
|
+
contentLevel: 'ENTERPRISE',
|
|
95
|
+
});
|
|
96
|
+
expect(mockPromptUser).toHaveBeenCalledTimes(2);
|
|
97
|
+
});
|
|
98
|
+
it('should allow manual tier selection', async () => {
|
|
99
|
+
const mockPromptUser = vi.mocked(promptUtils.promptUser);
|
|
100
|
+
mockPromptUser.mockResolvedValueOnce({
|
|
101
|
+
accountName: 'TestAccount',
|
|
102
|
+
description: 'Test',
|
|
103
|
+
}); // name/description
|
|
104
|
+
mockPromptUser.mockResolvedValueOnce({
|
|
105
|
+
useDefaultAccountLevels: 'manual',
|
|
106
|
+
}); // tier choice
|
|
107
|
+
mockPromptUser.mockResolvedValueOnce({
|
|
108
|
+
testAccountLevels: [
|
|
109
|
+
{ hub: 'MARKETING', tier: 'PROFESSIONAL' },
|
|
110
|
+
{ hub: 'OPS', tier: 'STARTER' },
|
|
111
|
+
{ hub: 'SERVICE', tier: 'ENTERPRISE' },
|
|
112
|
+
{ hub: 'SALES', tier: 'FREE' },
|
|
113
|
+
{ hub: 'CONTENT', tier: 'ENTERPRISE' },
|
|
114
|
+
],
|
|
115
|
+
}); // manual tier selection
|
|
116
|
+
const result = await createDeveloperTestAccountConfigPrompt({});
|
|
117
|
+
expect(result).toEqual({
|
|
118
|
+
accountName: 'TestAccount',
|
|
119
|
+
description: 'Test',
|
|
120
|
+
marketingLevel: 'PROFESSIONAL',
|
|
121
|
+
opsLevel: 'STARTER',
|
|
122
|
+
serviceLevel: 'ENTERPRISE',
|
|
123
|
+
salesLevel: 'FREE',
|
|
124
|
+
contentLevel: 'ENTERPRISE',
|
|
125
|
+
});
|
|
126
|
+
expect(mockPromptUser).toHaveBeenCalledTimes(3);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
describe('with only name provided', () => {
|
|
130
|
+
it('should skip name prompt but show description and tier prompts', async () => {
|
|
131
|
+
const mockPromptUser = vi.mocked(promptUtils.promptUser);
|
|
132
|
+
mockPromptUser.mockResolvedValueOnce({
|
|
133
|
+
description: 'Prompted description',
|
|
134
|
+
}); // description prompt (name skipped)
|
|
135
|
+
mockPromptUser.mockResolvedValueOnce({
|
|
136
|
+
useDefaultAccountLevels: 'default',
|
|
137
|
+
}); // tier selection
|
|
138
|
+
const result = await createDeveloperTestAccountConfigPrompt({
|
|
139
|
+
name: 'TestAccount',
|
|
140
|
+
});
|
|
141
|
+
expect(result).toEqual({
|
|
142
|
+
accountName: 'TestAccount',
|
|
143
|
+
description: 'Prompted description',
|
|
144
|
+
marketingLevel: 'ENTERPRISE',
|
|
145
|
+
opsLevel: 'ENTERPRISE',
|
|
146
|
+
serviceLevel: 'ENTERPRISE',
|
|
147
|
+
salesLevel: 'ENTERPRISE',
|
|
148
|
+
contentLevel: 'ENTERPRISE',
|
|
149
|
+
});
|
|
150
|
+
expect(mockPromptUser).toHaveBeenCalledTimes(2);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getConfigAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { fetchProjects } from '@hubspot/local-dev-lib/api/projects';
|
|
3
3
|
import { downloadProjectPrompt } from '../downloadProjectPrompt.js';
|
|
4
4
|
vi.mock('../promptUtils', () => ({
|
|
@@ -10,15 +10,17 @@ vi.mock('@hubspot/local-dev-lib/api/projects', () => ({
|
|
|
10
10
|
}),
|
|
11
11
|
}));
|
|
12
12
|
vi.mock('@hubspot/local-dev-lib/config', () => ({
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
getConfigAccountIfExists: vi
|
|
14
|
+
.fn()
|
|
15
|
+
.mockImplementation(() => ({ accountId: 123456789 })),
|
|
16
|
+
globalConfigFileExists: vi.fn().mockReturnValue(true),
|
|
15
17
|
}));
|
|
16
18
|
describe('lib/prompts/downloadProjectPrompt', () => {
|
|
17
19
|
it('should honor the account passed as an option', async () => {
|
|
18
20
|
const account = 'Prod';
|
|
19
21
|
await downloadProjectPrompt({ account });
|
|
20
|
-
expect(
|
|
21
|
-
expect(
|
|
22
|
+
expect(getConfigAccountIfExists).toHaveBeenCalledTimes(1);
|
|
23
|
+
expect(getConfigAccountIfExists).toHaveBeenCalledWith(account);
|
|
22
24
|
});
|
|
23
25
|
it('should fetch the projects for the correct accountId', async () => {
|
|
24
26
|
const account = 'Prod';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getConfigAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { promptUser } from './promptUtils.js';
|
|
3
3
|
import { lib } from '../../lang/en.js';
|
|
4
4
|
import { HUBSPOT_ACCOUNT_TYPES } from '@hubspot/local-dev-lib/constants/config';
|
|
@@ -17,7 +17,7 @@ export function getCliAccountNamePromptConfig(defaultName) {
|
|
|
17
17
|
else if (val.indexOf(' ') >= 0) {
|
|
18
18
|
return lib.prompts.accountNamePrompt.errors.spacesInName;
|
|
19
19
|
}
|
|
20
|
-
return
|
|
20
|
+
return getConfigAccountIfExists(val)
|
|
21
21
|
? lib.prompts.accountNamePrompt.errors.accountNameExists(val)
|
|
22
22
|
: true;
|
|
23
23
|
},
|
|
@@ -54,7 +54,7 @@ export function hubspotAccountNamePrompt({ accountType, currentPortalCount = 0,
|
|
|
54
54
|
else if (!val.trim().length) {
|
|
55
55
|
return lib.prompts.accountNamePrompt.errors.nameRequired;
|
|
56
56
|
}
|
|
57
|
-
return
|
|
57
|
+
return getConfigAccountIfExists(val)
|
|
58
58
|
? lib.prompts.accountNamePrompt.errors.accountNameExists(val)
|
|
59
59
|
: true;
|
|
60
60
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function selectAccountFromConfig(prompt?: string): Promise<
|
|
1
|
+
export declare function selectAccountFromConfig(prompt?: string): Promise<number>;
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getAccountIdentifier } from '@hubspot/local-dev-lib/config/getAccountIdentifier';
|
|
1
|
+
import { getConfigDefaultAccountIfExists, getAllConfigAccounts, } from '@hubspot/local-dev-lib/config';
|
|
3
2
|
import { promptUser } from './promptUtils.js';
|
|
4
3
|
import { commands } from '../../lang/en.js';
|
|
5
4
|
import { uiAccountDescription } from '../ui/index.js';
|
|
6
5
|
function mapAccountChoices(portals) {
|
|
7
6
|
return (portals?.map(p => ({
|
|
8
|
-
name: uiAccountDescription(
|
|
9
|
-
value:
|
|
7
|
+
name: uiAccountDescription(p.accountId, false),
|
|
8
|
+
value: p.accountId,
|
|
10
9
|
})) || []);
|
|
11
10
|
}
|
|
12
11
|
export async function selectAccountFromConfig(prompt = '') {
|
|
13
|
-
const accountsList =
|
|
14
|
-
const defaultAccount =
|
|
12
|
+
const accountsList = getAllConfigAccounts();
|
|
13
|
+
const defaultAccount = getConfigDefaultAccountIfExists();
|
|
15
14
|
const { default: selectedDefault } = await promptUser([
|
|
16
15
|
{
|
|
17
16
|
type: 'list',
|
|
@@ -19,7 +18,7 @@ export async function selectAccountFromConfig(prompt = '') {
|
|
|
19
18
|
pageSize: 20,
|
|
20
19
|
message: prompt || commands.account.subcommands.use.promptMessage,
|
|
21
20
|
choices: mapAccountChoices(accountsList),
|
|
22
|
-
default: defaultAccount ?? undefined,
|
|
21
|
+
default: defaultAccount?.accountId ?? undefined,
|
|
23
22
|
},
|
|
24
23
|
]);
|
|
25
24
|
return selectedDefault;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { promptUser } from './promptUtils.js';
|
|
3
3
|
import { lib } from '../../lang/en.js';
|
|
4
4
|
export async function confirmImportDataPrompt(targetAccountId, dataFileNames) {
|
|
5
|
-
const account =
|
|
5
|
+
const account = getConfigAccountById(targetAccountId);
|
|
6
6
|
const { confirmImportData } = await promptUser({
|
|
7
7
|
type: 'confirm',
|
|
8
8
|
name: 'confirmImportData',
|
|
@@ -14,5 +14,10 @@ export type HubConfig = {
|
|
|
14
14
|
export declare function createDeveloperTestAccountConfigPrompt(args?: {
|
|
15
15
|
name?: string;
|
|
16
16
|
description?: string;
|
|
17
|
+
marketingLevel?: AccountLevel;
|
|
18
|
+
opsLevel?: AccountLevel;
|
|
19
|
+
serviceLevel?: AccountLevel;
|
|
20
|
+
salesLevel?: AccountLevel;
|
|
21
|
+
contentLevel?: AccountLevel;
|
|
17
22
|
}, supportFlags?: boolean): Promise<DeveloperTestAccountConfig>;
|
|
18
23
|
export {};
|