@hubspot/cli 7.9.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/__tests__/project.test.js +2 -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 +17 -23
- 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 +8 -16
- 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/cms/theme/preview.js +1 -4
- 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 +15 -22
- 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__/updateDeps.test.js +142 -0
- package/commands/project/__tests__/validate.test.js +2 -2
- package/commands/project/cloneApp.js +2 -2
- package/commands/project/create.js +0 -1
- 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/updateDeps.d.ts +6 -0
- package/commands/project/updateDeps.js +80 -0
- package/commands/project/upload.js +9 -3
- package/commands/project/validate.js +9 -3
- package/commands/project/watch.js +7 -2
- package/commands/project.js +2 -0
- package/commands/sandbox/__tests__/create.test.js +14 -5
- package/commands/sandbox/create.js +4 -5
- package/commands/sandbox/delete.js +23 -20
- package/commands/testAccount/__tests__/create.test.js +68 -0
- package/commands/testAccount/create.d.ts +8 -0
- package/commands/testAccount/create.js +135 -45
- package/commands/testAccount/delete.js +9 -8
- package/commands/testAccount/importData.d.ts +1 -1
- package/lang/en.d.ts +3199 -3185
- package/lang/en.js +52 -14
- package/lib/__tests__/buildAccount.test.js +22 -30
- package/lib/__tests__/commonOpts.test.js +9 -13
- package/lib/__tests__/dependencyManagement.test.js +273 -1
- 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 +5 -8
- 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/dependencyManagement.d.ts +8 -2
- package/lib/dependencyManagement.js +75 -12
- 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.d.ts +1 -0
- 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/npm.d.ts +3 -0
- package/lib/npm.js +6 -0
- 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__/platformVersion.test.js +5 -1
- 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/platformVersion.js +1 -1
- 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/lang/en.lyaml +0 -1508
- package/lib/lang.d.ts +0 -8
- package/lib/lang.js +0 -72
- 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 → commands/project/__tests__/updateDeps.test.d.ts} +0 -0
package/lang/en.js
CHANGED
|
@@ -7,15 +7,15 @@ import { uiAccountDescription, uiBetaTag, uiCommandReference, uiLink, UI_COLORS,
|
|
|
7
7
|
import { getProjectDetailUrl, getProjectSettingsUrl, getLocalDevUiUrl, } from '../lib/projects/urls.js';
|
|
8
8
|
import { getProductUpdatesUrl } from '../lib/links.js';
|
|
9
9
|
import { APP_DISTRIBUTION_TYPES, APP_AUTH_TYPES, PROJECT_CONFIG_FILE, PROJECT_WITH_APP, LEGACY_PUBLIC_APP_FILE, } from '../lib/constants.js';
|
|
10
|
-
import { getAccountIdentifier } from '@hubspot/local-dev-lib/config/getAccountIdentifier';
|
|
11
10
|
export const commands = {
|
|
12
11
|
generalErrors: {
|
|
13
12
|
srcIsProject: (src, command) => `"${src}" is in a project folder. Did you mean "hs project ${command}"?`,
|
|
14
13
|
handleDeprecatedEnvVariables: {
|
|
15
14
|
portalEnvVarDeprecated: 'The HUBSPOT_PORTAL_ID environment variable is deprecated. Please use HUBSPOT_ACCOUNT_ID instead.',
|
|
16
15
|
},
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
validateConfigMiddleware: {
|
|
17
|
+
missingConfigFile: `A HubSpot config file is required to run this command, but none was found. To create a new config file and authenticate a HubSpot account, run ${uiCommandReference('hs account auth')}`,
|
|
18
|
+
configValidationFailed: (errors) => `Your HubSpot config file is invalid. Please fix the following errors:\n - ${errors.join('\n- ')}`,
|
|
19
19
|
},
|
|
20
20
|
},
|
|
21
21
|
getStarted: {
|
|
@@ -51,12 +51,11 @@ export const commands = {
|
|
|
51
51
|
uploadProject: (accountName) => `Would you like to upload this project to account "${accountName}" now?`,
|
|
52
52
|
projectCreated: {
|
|
53
53
|
title: chalk.bold('Next steps:'),
|
|
54
|
-
description: `Let's prepare and upload your project to HubSpot.\nYou can use ${uiCommandReference('hs project
|
|
54
|
+
description: `Let's prepare and upload your project to HubSpot.\nYou can use ${uiCommandReference('hs project upload')} to ${chalk.bold('upload')} your project.`,
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
logs: {
|
|
58
58
|
appSelected: `We'll create a new project with a sample app for you.\nProjects are what you can use to create apps with HubSpot.\nUsually you'll use the ${uiCommandReference('hs project create')} command, but we'll go ahead and make one now.`,
|
|
59
|
-
dependenciesInstalled: 'Dependencies installed successfully.',
|
|
60
59
|
uploadingProject: 'Uploading your project to HubSpot...',
|
|
61
60
|
uploadSuccess: 'Project uploaded successfully!',
|
|
62
61
|
developerOverviewLink: 'Open this link to navigate to your HubSpot developer portal',
|
|
@@ -64,7 +63,6 @@ export const commands = {
|
|
|
64
63
|
errors: {
|
|
65
64
|
uploadFailed: 'Failed to upload project to HubSpot.',
|
|
66
65
|
configFileNotFound: 'Could not find project configuration for upload.',
|
|
67
|
-
installDepsFailed: 'Failed to install dependencies.',
|
|
68
66
|
},
|
|
69
67
|
},
|
|
70
68
|
completion: {
|
|
@@ -120,7 +118,7 @@ export const commands = {
|
|
|
120
118
|
},
|
|
121
119
|
},
|
|
122
120
|
success: {
|
|
123
|
-
renamed: (name, newName) => `Account "${name}" renamed to "${newName}"
|
|
121
|
+
renamed: (name, newName, nameWasSanitized) => `Account "${chalk.bold(name)}" successfully renamed to "${chalk.bold(newName)}"${nameWasSanitized ? ' (Sanitized to remove invalid characters)' : ''}.`,
|
|
124
122
|
},
|
|
125
123
|
},
|
|
126
124
|
use: {
|
|
@@ -1198,6 +1196,7 @@ export const commands = {
|
|
|
1198
1196
|
setup: {
|
|
1199
1197
|
describe: 'Setup the HubSpot development MCP servers.',
|
|
1200
1198
|
installingDocSearch: 'Adding the docs-search mcp server',
|
|
1199
|
+
codex: 'Codex CLI',
|
|
1201
1200
|
claudeCode: 'Claude Code',
|
|
1202
1201
|
cursor: 'Cursor',
|
|
1203
1202
|
windsurf: 'Windsurf',
|
|
@@ -1219,7 +1218,11 @@ export const commands = {
|
|
|
1219
1218
|
configuredClaudeCode: 'Configured Claude Code',
|
|
1220
1219
|
claudeCodeNotFound: 'Claude Code not found - skipping configuration',
|
|
1221
1220
|
claudeCodeInstallFailed: 'Claude Code CLI not working - skipping configuration',
|
|
1222
|
-
|
|
1221
|
+
// Codex
|
|
1222
|
+
configuringCodex: 'Configuring Codex...',
|
|
1223
|
+
configuredCodex: 'Configured Codex',
|
|
1224
|
+
codexNotFound: 'Codex command not found - skipping configuration',
|
|
1225
|
+
codexInstallFailed: 'Failed to configure Codex',
|
|
1223
1226
|
// Cursor
|
|
1224
1227
|
configuringCursor: 'Configuring Cursor...',
|
|
1225
1228
|
failedToConfigureCursor: 'Failed to configure Cursor',
|
|
@@ -1765,6 +1768,22 @@ export const commands = {
|
|
|
1765
1768
|
noPackageJsonInProject: (projectName) => `No dependencies to install. The project ${projectName} folder might be missing component or subcomponent files. ${uiLink('Learn how to create a project from scratch', 'https://developers.hubspot.com/docs/apps/developer-platform/build-apps/create-an-app#customize-a-new-project-using-the-cli')}`,
|
|
1766
1769
|
packageManagerNotInstalled: (packageManager) => `This command depends on ${packageManager}, install ${uiLink(packageManager, 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm')}`,
|
|
1767
1770
|
},
|
|
1771
|
+
updateDeps: {
|
|
1772
|
+
help: {
|
|
1773
|
+
describe: 'Update the npm dependencies for your project, or update specific dependencies in a subcomponent of a project.',
|
|
1774
|
+
updateAppDepsExample: 'Update the dependencies for the project',
|
|
1775
|
+
updateDepToSubComponentExample: 'Update the npm dependencies in one or more project subcomponents',
|
|
1776
|
+
},
|
|
1777
|
+
installLocationPrompt: 'Choose which project components you would like to update the dependencies for:',
|
|
1778
|
+
installLocationPromptRequired: 'You must choose at least one subcomponent',
|
|
1779
|
+
updatingDependencies: (directory) => `Updating dependencies in ${directory}`,
|
|
1780
|
+
updateSuccessful: (directory) => `Updated dependencies in ${directory}`,
|
|
1781
|
+
updatingDependenciesToLocation: (dependencies, directory) => `Updating ${dependencies} in ${directory}`,
|
|
1782
|
+
updatingDependenciesFailed: (directory) => `Updating dependencies for ${directory} failed`,
|
|
1783
|
+
noProjectConfig: 'No project detected. Run this command from a project directory.',
|
|
1784
|
+
noPackageJsonInProject: (projectName) => `No dependencies to update. The project ${projectName} folder might be missing component or subcomponent files. ${uiLink('Learn how to create a project from scratch', 'https://developers.hubspot.com/docs/apps/developer-platform/build-apps/create-an-app#customize-a-new-project-using-the-cli')}`,
|
|
1785
|
+
packageManagerNotInstalled: (packageManager) => `This command depends on ${packageManager}, install ${uiLink(packageManager, 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm')}`,
|
|
1786
|
+
},
|
|
1768
1787
|
validate: {
|
|
1769
1788
|
describe: 'Validate the project before uploading',
|
|
1770
1789
|
mustBeRanWithinAProject: 'This command must be run from within a project directory.',
|
|
@@ -2082,7 +2101,7 @@ export const commands = {
|
|
|
2082
2101
|
},
|
|
2083
2102
|
},
|
|
2084
2103
|
create: {
|
|
2085
|
-
describe:
|
|
2104
|
+
describe: `Create a test account from scratch or from a config file. Use ${uiCommandReference('hs test-account create-config')} to generate a config file. \n${uiLink('Learn more', 'https://developers.hubspot.com/docs/developer-tooling/local-development/configurable-test-accounts')}`,
|
|
2086
2105
|
configPathPrompt: '[--config-path] Enter the path to the test account config: ',
|
|
2087
2106
|
createTestAccountFromConfigPrompt: 'How would you like to create your test account?',
|
|
2088
2107
|
createFromConfigOption: 'Create test account from config file',
|
|
@@ -2099,9 +2118,21 @@ export const commands = {
|
|
|
2099
2118
|
createFailure: 'Failed to create test account.',
|
|
2100
2119
|
},
|
|
2101
2120
|
options: {
|
|
2102
|
-
configPath: '
|
|
2121
|
+
configPath: 'Path to config file (mutually exclusive with other flags)',
|
|
2122
|
+
accountName: 'Name for the test account',
|
|
2123
|
+
description: 'Description for the test account',
|
|
2124
|
+
marketingLevel: 'Marketing Hub tier. Options: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
|
|
2125
|
+
opsLevel: 'Operations Hub tier. Options: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
|
|
2126
|
+
serviceLevel: 'Service Hub tier. Options: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
|
|
2127
|
+
salesLevel: 'Sales Hub tier. Options: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
|
|
2128
|
+
contentLevel: 'CMS Hub tier. Options: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
|
|
2103
2129
|
},
|
|
2104
2130
|
example: (configPath) => `Create a test account from the config file at ${configPath}`,
|
|
2131
|
+
examples: {
|
|
2132
|
+
withAllHubsEnterprise: 'Create a test account with all hubs at ENTERPRISE level',
|
|
2133
|
+
withSpecificHubLevels: 'Create a test account with specific hub levels',
|
|
2134
|
+
},
|
|
2135
|
+
savedAccountNameDiffers: (originalName, savedName) => `Account name "${chalk.bold(originalName)}" was saved as "${chalk.bold(savedName)}" in config.`,
|
|
2105
2136
|
},
|
|
2106
2137
|
createConfig: {
|
|
2107
2138
|
describe: 'Create a test account config file.',
|
|
@@ -2964,12 +2995,16 @@ export const lib = {
|
|
|
2964
2995
|
},
|
|
2965
2996
|
},
|
|
2966
2997
|
add: {
|
|
2967
|
-
nothingAdded: 'No features added.',
|
|
2998
|
+
nothingAdded: 'No features were added to the project. Use the space bar to select features from the list.',
|
|
2968
2999
|
},
|
|
2969
3000
|
updateHsMetaFilesWithAutoGeneratedFields: {
|
|
2970
3001
|
header: 'Created the following components and features:',
|
|
2971
3002
|
applicationLog: (componentType, uid, name) => ` - Created ${chalk.bold(componentType)} with uid ${chalk.bold(uid)} and name ${chalk.bold(name)}`,
|
|
2972
3003
|
componentLog: (componentType, uid) => ` - Created ${chalk.bold(componentType)} feature with uid ${chalk.bold(uid)}`,
|
|
3004
|
+
failedToUpdate: (hsMetaFile) => `Failed to update the uid in ${chalk.bold(hsMetaFile)}`,
|
|
3005
|
+
},
|
|
3006
|
+
generateSafeFilenameDifferentiator: {
|
|
3007
|
+
failedToCheckFiles: 'Failed to check files for filename differentiator. Falling back to timestamp.',
|
|
2973
3008
|
},
|
|
2974
3009
|
validateProjectConfig: {
|
|
2975
3010
|
configNotFound: `Unable to locate a project configuration file. Try running again from a project directory, or run ${uiCommandReference('hs project create')} to create a new project.`,
|
|
@@ -3218,6 +3253,9 @@ export const lib = {
|
|
|
3218
3253
|
skippedExistingAccounts: (accountIds) => `The following accounts were not merged because they already exist in the global config:${accountIds.map(id => `\n- ${uiAccountDescription(Number(id))}`).join('')}`,
|
|
3219
3254
|
success: 'Your deprecated config file has been successfully merged with the global config file.',
|
|
3220
3255
|
},
|
|
3256
|
+
errors: {
|
|
3257
|
+
archive: (deprecatedConfigPath) => `The config migration was successful, but an error occurred when archiving config file at ${deprecatedConfigPath}. You may need to manually delete or rename this config file.`,
|
|
3258
|
+
},
|
|
3221
3259
|
},
|
|
3222
3260
|
prompts: {
|
|
3223
3261
|
promptUtils: {
|
|
@@ -3230,7 +3268,7 @@ export const lib = {
|
|
|
3230
3268
|
promptMessage: '[--file-path] Select the JSON file that will be used to import your data.',
|
|
3231
3269
|
},
|
|
3232
3270
|
confirmImportDataPrompt: {
|
|
3233
|
-
message: (dataFileNames, cliAccount) => `You are importing [${dataFileNames.join(', ')}] into ${uiAccountDescription(
|
|
3271
|
+
message: (dataFileNames, cliAccount) => `You are importing [${dataFileNames.join(', ')}] into ${uiAccountDescription(cliAccount?.accountId)}. Continue?`,
|
|
3234
3272
|
},
|
|
3235
3273
|
importDataTestAccountSelectPrompt: {
|
|
3236
3274
|
errors: {
|
|
@@ -3582,7 +3620,7 @@ export const lib = {
|
|
|
3582
3620
|
},
|
|
3583
3621
|
failure: {
|
|
3584
3622
|
syncTypeFetch: 'Unable to fetch available sandbox sync types. Please try again.',
|
|
3585
|
-
invalidUser: (accountName, parentAccountName) => `Couldn't sync ${chalk.bold(accountName)} because your account has been removed from ${chalk.bold(parentAccountName)} or your permission set doesn't allow you to sync the sandbox. To update your permissions, contact a super admin in ${chalk.bold(parentAccountName)}.`,
|
|
3623
|
+
invalidUser: (accountName, parentAccountName) => `Couldn't sync sandbox ${chalk.bold(accountName)} because your account has been removed from parent account${chalk.bold(parentAccountName)} or your permission set doesn't allow you to sync the sandbox. To update your permissions, contact a super admin in ${chalk.bold(parentAccountName)}.`,
|
|
3586
3624
|
syncInProgress: (url) => `Couldn't run the sync because there's another sync in progress. Wait for the current sync to finish and then try again. To check the sync status, visit the sync activity log: ${url}.`,
|
|
3587
3625
|
notSuperAdmin: (accountId) => `Couldn't run the sync because you are not a super admin in ${uiAccountDescription(accountId)}. Ask the account owner for super admin access to the sandbox.`,
|
|
3588
3626
|
objectNotFound: (accountId) => `Couldn't sync the sandbox because ${uiAccountDescription(accountId)} may have been deleted through the UI. Run ${uiCommandReference('hs sandbox delete')} to remove this account from the config.`,
|
|
@@ -3710,7 +3748,7 @@ export const lib = {
|
|
|
3710
3748
|
},
|
|
3711
3749
|
validation: {
|
|
3712
3750
|
accountNotFoundInConfig: (userProvidedAccount) => `The account "${userProvidedAccount}" could not be found in the config`,
|
|
3713
|
-
accountRequired: 'An account needs to be supplied either via "--account" or through setting a "
|
|
3751
|
+
accountRequired: 'An account needs to be supplied either via "--account" or through setting a "defaultAccount"',
|
|
3714
3752
|
userProvidedAccount: 'Cannot specify an account when environment variables are supplied. Please unset the environment variables or do not use the "--account" flag.',
|
|
3715
3753
|
accountNotConfigured: (accountId) => `The account ${uiAccountDescription(accountId)} has not been configured`,
|
|
3716
3754
|
invalidAuthType: (authType, accountId, configPath, validValues) => `Invalid "authType" value "${authType}" for account "${uiAccountDescription(accountId)}" in config file: ${configPath}. Valid values are ${validValues}.`,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { getAccessToken, updateConfigWithAccessToken, } from '@hubspot/local-dev-lib/personalAccessKey';
|
|
2
|
-
import {
|
|
2
|
+
import { getConfigAccountIfExists, updateConfigAccount, } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { createDeveloperTestAccount, fetchDeveloperTestAccountGateSyncStatus, generateDeveloperTestAccountPersonalAccessKey, } from '@hubspot/local-dev-lib/api/developerTestAccounts';
|
|
4
4
|
import { createSandbox, createV2Sandbox, getSandboxPersonalAccessKey, } from '@hubspot/local-dev-lib/api/sandboxHubs';
|
|
5
5
|
import { HUBSPOT_ACCOUNT_TYPES } from '@hubspot/local-dev-lib/constants/config';
|
|
6
6
|
import { personalAccessKeyPrompt } from '../prompts/personalAccessKeyPrompt.js';
|
|
7
7
|
import { cliAccountNamePrompt } from '../prompts/accountNamePrompt.js';
|
|
8
8
|
import * as buildAccount from '../buildAccount.js';
|
|
9
|
+
import { poll } from '../polling.js';
|
|
9
10
|
vi.mock('@hubspot/local-dev-lib/personalAccessKey');
|
|
10
11
|
vi.mock('@hubspot/local-dev-lib/config');
|
|
11
12
|
vi.mock('@hubspot/local-dev-lib/api/developerTestAccounts');
|
|
@@ -14,6 +15,7 @@ vi.mock('../ui/logger.js');
|
|
|
14
15
|
vi.mock('../errorHandlers/index.js');
|
|
15
16
|
vi.mock('../prompts/personalAccessKeyPrompt');
|
|
16
17
|
vi.mock('../prompts/accountNamePrompt');
|
|
18
|
+
vi.mock('../polling.js');
|
|
17
19
|
vi.mock('../ui/SpinniesManager', () => ({
|
|
18
20
|
default: {
|
|
19
21
|
init: vi.fn(),
|
|
@@ -25,17 +27,16 @@ vi.mock('../ui/SpinniesManager', () => ({
|
|
|
25
27
|
const mockedPersonalAccessKeyPrompt = personalAccessKeyPrompt;
|
|
26
28
|
const mockedGetAccessToken = getAccessToken;
|
|
27
29
|
const mockedUpdateConfigWithAccessToken = updateConfigWithAccessToken;
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const mockedWriteConfig = writeConfig;
|
|
30
|
+
const mockedGetConfigAccountIfExists = getConfigAccountIfExists;
|
|
31
|
+
const mockedUpdateConfigAccount = updateConfigAccount;
|
|
31
32
|
const mockedCliAccountNamePrompt = cliAccountNamePrompt;
|
|
32
|
-
const mockedGetAccountId = getAccountId;
|
|
33
33
|
const mockedCreateDeveloperTestAccount = createDeveloperTestAccount;
|
|
34
34
|
const mockedFetchDeveloperTestAccountGateSyncStatus = fetchDeveloperTestAccountGateSyncStatus;
|
|
35
35
|
const mockedGenerateDeveloperTestAccountPersonalAccessKey = generateDeveloperTestAccountPersonalAccessKey;
|
|
36
36
|
const mockedCreateSandbox = createSandbox;
|
|
37
37
|
const mockedCreateV2Sandbox = createV2Sandbox;
|
|
38
38
|
const mockedGetPersonalAccessKey = getSandboxPersonalAccessKey;
|
|
39
|
+
const mockedPoll = poll;
|
|
39
40
|
describe('lib/buildAccount', () => {
|
|
40
41
|
describe('saveAccountToConfig()', () => {
|
|
41
42
|
const mockAccountConfig = {
|
|
@@ -61,9 +62,8 @@ describe('lib/buildAccount', () => {
|
|
|
61
62
|
});
|
|
62
63
|
mockedGetAccessToken.mockResolvedValue(accessToken);
|
|
63
64
|
mockedUpdateConfigWithAccessToken.mockResolvedValue(mockAccountConfig);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
mockedWriteConfig.mockReturnValue(undefined);
|
|
65
|
+
mockedGetConfigAccountIfExists.mockResolvedValue(undefined);
|
|
66
|
+
mockedUpdateConfigAccount.mockReturnValue(undefined);
|
|
67
67
|
});
|
|
68
68
|
afterEach(() => {
|
|
69
69
|
vi.clearAllMocks();
|
|
@@ -72,8 +72,7 @@ describe('lib/buildAccount', () => {
|
|
|
72
72
|
const result = await buildAccount.saveAccountToConfig(mockAccountConfig.accountId, mockAccountConfig.name, mockAccountConfig.env, 'test-key');
|
|
73
73
|
expect(mockedPersonalAccessKeyPrompt).not.toHaveBeenCalled();
|
|
74
74
|
expect(mockedUpdateConfigWithAccessToken).toHaveBeenCalledWith(accessToken, 'test-key', mockAccountConfig.env);
|
|
75
|
-
expect(
|
|
76
|
-
expect(mockedWriteConfig).toHaveBeenCalled();
|
|
75
|
+
expect(mockedUpdateConfigAccount).toHaveBeenCalledWith(expect.objectContaining(mockAccountConfig));
|
|
77
76
|
expect(result).toBe(mockAccountConfig.name);
|
|
78
77
|
});
|
|
79
78
|
it('should prompt for personal access key if not provided', async () => {
|
|
@@ -83,8 +82,7 @@ describe('lib/buildAccount', () => {
|
|
|
83
82
|
account: mockAccountConfig.accountId,
|
|
84
83
|
});
|
|
85
84
|
expect(mockedUpdateConfigWithAccessToken).toHaveBeenCalledWith(accessToken, 'test-key', mockAccountConfig.env);
|
|
86
|
-
expect(
|
|
87
|
-
expect(mockedWriteConfig).toHaveBeenCalled();
|
|
85
|
+
expect(mockedUpdateConfigAccount).toHaveBeenCalledWith(expect.objectContaining(mockAccountConfig));
|
|
88
86
|
expect(result).toBe(mockAccountConfig.name);
|
|
89
87
|
});
|
|
90
88
|
it('should handle duplicate account names', async () => {
|
|
@@ -93,7 +91,7 @@ describe('lib/buildAccount', () => {
|
|
|
93
91
|
name: undefined,
|
|
94
92
|
};
|
|
95
93
|
mockedUpdateConfigWithAccessToken.mockResolvedValue(mockAccountConfigWithNoName);
|
|
96
|
-
|
|
94
|
+
mockedGetConfigAccountIfExists.mockResolvedValue({ accountId: 123 });
|
|
97
95
|
mockedCliAccountNamePrompt.mockResolvedValue({
|
|
98
96
|
name: 'test-account-with-new-name',
|
|
99
97
|
});
|
|
@@ -109,6 +107,7 @@ describe('lib/buildAccount', () => {
|
|
|
109
107
|
description: 'Test Account created by the HubSpot CLI',
|
|
110
108
|
};
|
|
111
109
|
beforeEach(() => {
|
|
110
|
+
vi.useFakeTimers();
|
|
112
111
|
mockedCreateDeveloperTestAccount.mockResolvedValue({
|
|
113
112
|
data: { id: 123456 },
|
|
114
113
|
});
|
|
@@ -118,15 +117,23 @@ describe('lib/buildAccount', () => {
|
|
|
118
117
|
mockedGenerateDeveloperTestAccountPersonalAccessKey.mockResolvedValue({
|
|
119
118
|
data: { personalAccessKey: 'test-key' },
|
|
120
119
|
});
|
|
120
|
+
// Mock poll to resolve immediately with the success status
|
|
121
|
+
mockedPoll.mockResolvedValue({ status: 'SUCCESS' });
|
|
122
|
+
});
|
|
123
|
+
afterEach(() => {
|
|
124
|
+
vi.useRealTimers();
|
|
121
125
|
});
|
|
122
126
|
it('should create a developer test account successfully', async () => {
|
|
123
|
-
const
|
|
127
|
+
const resultPromise = buildAccount.createDeveloperTestAccountV2(parentAccountId, mockDeveoperTestAccountConfig);
|
|
128
|
+
// Fast-forward the 5 second setTimeout
|
|
129
|
+
await vi.advanceTimersByTimeAsync(5000);
|
|
130
|
+
const result = await resultPromise;
|
|
124
131
|
expect(result).toEqual({
|
|
125
132
|
accountName: mockDeveoperTestAccountConfig.accountName,
|
|
126
133
|
accountId: 123456,
|
|
127
134
|
personalAccessKey: 'test-key',
|
|
128
135
|
});
|
|
129
|
-
}
|
|
136
|
+
});
|
|
130
137
|
});
|
|
131
138
|
describe('buildDeveloperTestAccount()', () => {
|
|
132
139
|
const mockParentAccountConfig = {
|
|
@@ -146,7 +153,6 @@ describe('lib/buildAccount', () => {
|
|
|
146
153
|
};
|
|
147
154
|
beforeEach(() => {
|
|
148
155
|
vi.spyOn(buildAccount, 'saveAccountToConfig').mockResolvedValue(mockParentAccountConfig.name);
|
|
149
|
-
mockedGetAccountId.mockReturnValue(mockParentAccountConfig.accountId);
|
|
150
156
|
mockedCreateDeveloperTestAccount.mockResolvedValue({
|
|
151
157
|
data: mockDeveloperTestAccount,
|
|
152
158
|
});
|
|
@@ -158,10 +164,6 @@ describe('lib/buildAccount', () => {
|
|
|
158
164
|
const result = await buildAccount.buildDeveloperTestAccount(mockDeveloperTestAccount.accountName, mockParentAccountConfig, mockParentAccountConfig.env, 10);
|
|
159
165
|
expect(result).toEqual(mockDeveloperTestAccount.id);
|
|
160
166
|
});
|
|
161
|
-
it('should throw error if account ID is not found', async () => {
|
|
162
|
-
mockedGetAccountId.mockReturnValue(null);
|
|
163
|
-
await expect(buildAccount.buildDeveloperTestAccount(mockDeveloperTestAccount.accountName, mockParentAccountConfig, mockParentAccountConfig.env, 10)).rejects.toThrow();
|
|
164
|
-
});
|
|
165
167
|
it('should handle API errors when creating developer test account', async () => {
|
|
166
168
|
mockedCreateDeveloperTestAccount.mockRejectedValue(new Error('test-error'));
|
|
167
169
|
await expect(buildAccount.buildDeveloperTestAccount(mockDeveloperTestAccount.accountName, mockParentAccountConfig, mockParentAccountConfig.env, 10)).rejects.toThrow();
|
|
@@ -192,7 +194,6 @@ describe('lib/buildAccount', () => {
|
|
|
192
194
|
};
|
|
193
195
|
beforeEach(() => {
|
|
194
196
|
vi.spyOn(buildAccount, 'saveAccountToConfig').mockResolvedValue(mockParentAccountConfig.name);
|
|
195
|
-
mockedGetAccountId.mockReturnValue(mockParentAccountConfig.accountId);
|
|
196
197
|
mockedCreateSandbox.mockResolvedValue({
|
|
197
198
|
data: { sandbox: mockSandbox, personalAccessKey: 'test-key' },
|
|
198
199
|
});
|
|
@@ -216,10 +217,6 @@ describe('lib/buildAccount', () => {
|
|
|
216
217
|
sandbox: mockSandbox,
|
|
217
218
|
});
|
|
218
219
|
});
|
|
219
|
-
it('should throw error if account ID is not found', async () => {
|
|
220
|
-
mockedGetAccountId.mockReturnValue(null);
|
|
221
|
-
await expect(buildAccount.buildSandbox(mockSandbox.name, mockParentAccountConfig, HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX, mockParentAccountConfig.env)).rejects.toThrow();
|
|
222
|
-
});
|
|
223
220
|
it('should handle API errors when creating sandbox', async () => {
|
|
224
221
|
mockedCreateSandbox.mockRejectedValue(new Error('test-error'));
|
|
225
222
|
await expect(buildAccount.buildSandbox(mockSandbox.name, mockParentAccountConfig, HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX, mockParentAccountConfig.env, false)).rejects.toThrow();
|
|
@@ -250,7 +247,6 @@ describe('lib/buildAccount', () => {
|
|
|
250
247
|
};
|
|
251
248
|
beforeEach(() => {
|
|
252
249
|
vi.spyOn(buildAccount, 'saveAccountToConfig').mockResolvedValue(mockParentAccountConfig.name);
|
|
253
|
-
mockedGetAccountId.mockReturnValue(mockParentAccountConfig.accountId);
|
|
254
250
|
mockedCreateV2Sandbox.mockResolvedValue({
|
|
255
251
|
data: mockSandbox,
|
|
256
252
|
});
|
|
@@ -271,10 +267,6 @@ describe('lib/buildAccount', () => {
|
|
|
271
267
|
expect(result).toEqual({ sandbox: mockSandbox });
|
|
272
268
|
expect(mockedGetPersonalAccessKey).toHaveBeenCalledWith(mockParentAccountConfig.accountId, mockSandbox.sandboxHubId);
|
|
273
269
|
});
|
|
274
|
-
it('should throw error if account ID is not found', async () => {
|
|
275
|
-
mockedGetAccountId.mockReturnValue(null);
|
|
276
|
-
await expect(buildAccount.buildV2Sandbox(mockSandbox.name, mockParentAccountConfig, HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX, false, mockParentAccountConfig.env, false)).rejects.toThrow();
|
|
277
|
-
});
|
|
278
270
|
it('should handle API errors when creating sandbox', async () => {
|
|
279
271
|
mockedCreateV2Sandbox.mockRejectedValue(new Error('test-error'));
|
|
280
272
|
await expect(buildAccount.buildV2Sandbox(mockSandbox.name, mockParentAccountConfig, HUBSPOT_ACCOUNT_TYPES.STANDARD_SANDBOX, false, mockParentAccountConfig.env, false)).rejects.toThrow();
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { CMS_PUBLISH_MODE, DEFAULT_CMS_PUBLISH_MODE, } from '@hubspot/local-dev-lib/constants/files';
|
|
2
|
-
import {
|
|
2
|
+
import { getConfig, getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { getCmsPublishMode } from '../commonOpts.js';
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const mockedLoadConfigFromEnvironment = loadConfigFromEnvironment;
|
|
4
|
+
const mockedGetConfigAccountById = getConfigAccountById;
|
|
5
|
+
const mockedGetConfig = getConfig;
|
|
7
6
|
function buildArguments(args) {
|
|
8
7
|
return {
|
|
9
8
|
_: [],
|
|
@@ -42,8 +41,8 @@ describe('lib/commonOpts', () => {
|
|
|
42
41
|
describe('cms publish mode option precedence', () => {
|
|
43
42
|
describe('1. --cmsPublishMode', () => {
|
|
44
43
|
it('should return the cms publish mode specified by the command option if present.', () => {
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
mockedGetConfig.mockReturnValue(configWithDefaultCmsPublishMode);
|
|
45
|
+
mockedGetConfigAccountById.mockReturnValue(devAccountConfig);
|
|
47
46
|
expect(getCmsPublishMode(buildArguments({
|
|
48
47
|
cmsPublishMode: CMS_PUBLISH_MODE.draft,
|
|
49
48
|
}))).toBe(CMS_PUBLISH_MODE.draft);
|
|
@@ -54,9 +53,8 @@ describe('lib/commonOpts', () => {
|
|
|
54
53
|
});
|
|
55
54
|
describe('2. hubspot.config.yml -> config.accounts[x].defaultCmsPublishMode', () => {
|
|
56
55
|
it('should return the defaultCmsPublishMode specified by the account specific config if present.', () => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
mockedLoadConfigFromEnvironment.mockReturnValue(undefined);
|
|
56
|
+
mockedGetConfig.mockReturnValue(configWithDefaultCmsPublishMode);
|
|
57
|
+
mockedGetConfigAccountById.mockReturnValue(devAccountConfig);
|
|
60
58
|
expect(getCmsPublishMode(buildArguments({
|
|
61
59
|
account: accounts.DEV,
|
|
62
60
|
}))).toBe(CMS_PUBLISH_MODE.draft);
|
|
@@ -64,9 +62,8 @@ describe('lib/commonOpts', () => {
|
|
|
64
62
|
});
|
|
65
63
|
describe('3. hubspot.config.yml -> config.defaultCmsPublishMode', () => {
|
|
66
64
|
it('should return the defaultCmsPublishMode specified by the config if present.', () => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
mockedLoadConfigFromEnvironment.mockReturnValue(undefined);
|
|
65
|
+
mockedGetConfig.mockReturnValue(configWithDefaultCmsPublishMode);
|
|
66
|
+
mockedGetConfigAccountById.mockReturnValue(prodAccountConfig);
|
|
70
67
|
expect(getCmsPublishMode(buildArguments({
|
|
71
68
|
account: accounts.PROD,
|
|
72
69
|
}))).toBe(CMS_PUBLISH_MODE.draft);
|
|
@@ -74,7 +71,6 @@ describe('lib/commonOpts', () => {
|
|
|
74
71
|
});
|
|
75
72
|
describe('4. DEFAULT_CMS_PUBLISH_MODE', () => {
|
|
76
73
|
it('should return the defaultCmsPubishMode specified by the config if present.', () => {
|
|
77
|
-
mockedLoadConfigFromEnvironment.mockReturnValue(undefined);
|
|
78
74
|
expect(getCmsPublishMode(buildArguments({
|
|
79
75
|
account: 'xxxxx',
|
|
80
76
|
}))).toBe(DEFAULT_CMS_PUBLISH_MODE);
|