@hubspot/cli 7.9.0 → 7.10.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/commands/__tests__/project.test.js +2 -0
  2. package/commands/account/__tests__/rename.test.js +35 -0
  3. package/commands/account/createOverride.js +2 -12
  4. package/commands/account/removeOverride.js +2 -10
  5. package/commands/account/rename.d.ts +1 -1
  6. package/commands/account/rename.js +5 -2
  7. package/commands/cms/theme/preview.js +1 -4
  8. package/commands/config/set.js +1 -2
  9. package/commands/getStarted.js +13 -19
  10. package/commands/hubdb.d.ts +1 -1
  11. package/commands/project/__tests__/updateDeps.test.d.ts +1 -0
  12. package/commands/project/__tests__/updateDeps.test.js +142 -0
  13. package/commands/project/create.js +0 -1
  14. package/commands/project/dev/index.js +8 -1
  15. package/commands/project/listBuilds.js +7 -1
  16. package/commands/project/updateDeps.d.ts +6 -0
  17. package/commands/project/updateDeps.js +80 -0
  18. package/commands/project/upload.js +7 -1
  19. package/commands/project/validate.js +7 -1
  20. package/commands/project/watch.js +7 -2
  21. package/commands/project.js +2 -0
  22. package/commands/testAccount/__tests__/create.test.js +68 -0
  23. package/commands/testAccount/create.d.ts +8 -0
  24. package/commands/testAccount/create.js +134 -44
  25. package/commands/testAccount/importData.d.ts +1 -1
  26. package/lang/en.d.ts +3194 -3184
  27. package/lang/en.js +43 -8
  28. package/lib/__tests__/dependencyManagement.test.js +273 -1
  29. package/lib/commonOpts.js +2 -5
  30. package/lib/constants.d.ts +1 -0
  31. package/lib/constants.js +6 -0
  32. package/lib/dependencyManagement.d.ts +8 -2
  33. package/lib/dependencyManagement.js +75 -12
  34. package/lib/mcp/__tests__/setup.test.d.ts +1 -0
  35. package/lib/mcp/__tests__/setup.test.js +127 -0
  36. package/lib/mcp/setup.d.ts +4 -12
  37. package/lib/mcp/setup.js +34 -1
  38. package/lib/middleware/autoUpdateMiddleware.d.ts +3 -1
  39. package/lib/middleware/autoUpdateMiddleware.js +1 -0
  40. package/lib/npm.d.ts +3 -0
  41. package/lib/npm.js +6 -0
  42. package/lib/projects/__tests__/components.test.js +148 -24
  43. package/lib/projects/__tests__/platformVersion.test.js +5 -1
  44. package/lib/projects/__tests__/projects.test.js +13 -42
  45. package/lib/projects/components.js +76 -20
  46. package/lib/projects/config.js +5 -9
  47. package/lib/projects/platformVersion.js +1 -1
  48. package/lib/prompts/__tests__/createDeveloperTestAccountConfigPrompt.test.d.ts +1 -0
  49. package/lib/prompts/__tests__/createDeveloperTestAccountConfigPrompt.test.js +153 -0
  50. package/lib/prompts/createDeveloperTestAccountConfigPrompt.d.ts +5 -0
  51. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +76 -66
  52. package/mcp-server/tools/cms/HsCreateFunctionTool.js +6 -0
  53. package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +4 -4
  54. package/mcp-server/tools/cms/HsCreateModuleTool.js +6 -0
  55. package/mcp-server/tools/cms/HsCreateTemplateTool.js +6 -0
  56. package/mcp-server/tools/cms/HsFunctionLogsTool.d.ts +4 -4
  57. package/mcp-server/tools/cms/HsFunctionLogsTool.js +4 -0
  58. package/mcp-server/tools/cms/HsListFunctionsTool.js +4 -0
  59. package/mcp-server/tools/cms/HsListTool.js +4 -0
  60. package/mcp-server/tools/index.js +2 -0
  61. package/mcp-server/tools/project/AddFeatureToProjectTool.js +6 -0
  62. package/mcp-server/tools/project/CreateProjectTool.js +6 -0
  63. package/mcp-server/tools/project/CreateTestAccountTool.d.ts +41 -0
  64. package/mcp-server/tools/project/CreateTestAccountTool.js +137 -0
  65. package/mcp-server/tools/project/DeployProjectTool.js +6 -0
  66. package/mcp-server/tools/project/DocFetchTool.js +4 -0
  67. package/mcp-server/tools/project/DocsSearchTool.js +4 -0
  68. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +4 -0
  69. package/mcp-server/tools/project/GetApplicationInfoTool.js +4 -0
  70. package/mcp-server/tools/project/GetConfigValuesTool.js +4 -0
  71. package/mcp-server/tools/project/GuidedWalkthroughTool.js +4 -0
  72. package/mcp-server/tools/project/UploadProjectTools.d.ts +9 -3
  73. package/mcp-server/tools/project/UploadProjectTools.js +50 -4
  74. package/mcp-server/tools/project/ValidateProjectTool.js +4 -0
  75. package/mcp-server/tools/project/__tests__/CreateTestAccountTool.test.d.ts +1 -0
  76. package/mcp-server/tools/project/__tests__/CreateTestAccountTool.test.js +231 -0
  77. package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +2 -2
  78. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +56 -4
  79. package/package.json +2 -2
  80. package/lang/en.lyaml +0 -1508
  81. package/lib/lang.d.ts +0 -8
  82. package/lib/lang.js +0 -72
@@ -1,6 +1,7 @@
1
1
  import yargs from 'yargs';
2
2
  import { addAccountOptions, addConfigOptions, addUseEnvironmentOptions, addTestingOptions, addJSONOutputOptions, } from '../../../lib/commonOpts.js';
3
3
  import testAccountCreateCommand from '../create.js';
4
+ import { ACCOUNT_LEVEL_CHOICES } from '../../../lib/constants.js';
4
5
  vi.mock('../../../lib/commonOpts');
5
6
  describe('commands/testAccount/create', () => {
6
7
  const yargsMock = yargs;
@@ -29,5 +30,72 @@ describe('commands/testAccount/create', () => {
29
30
  expect(addJSONOutputOptions).toHaveBeenCalledTimes(1);
30
31
  expect(addJSONOutputOptions).toHaveBeenCalledWith(yargsMock);
31
32
  });
33
+ it('should add account-name option', () => {
34
+ testAccountCreateCommand.builder(yargsMock);
35
+ expect(yargsMock.option).toHaveBeenCalledWith('name', {
36
+ type: 'string',
37
+ description: 'Name for the test account',
38
+ });
39
+ });
40
+ it('should add description option', () => {
41
+ testAccountCreateCommand.builder(yargsMock);
42
+ expect(yargsMock.option).toHaveBeenCalledWith('description', {
43
+ type: 'string',
44
+ description: 'Description for the test account',
45
+ });
46
+ });
47
+ it('should add hub level options', () => {
48
+ testAccountCreateCommand.builder(yargsMock);
49
+ expect(yargsMock.option).toHaveBeenCalledWith('marketing-level', {
50
+ type: 'string',
51
+ description: 'Marketing Hub tier. Unprovided tiers default to ENTERPRISE. Choices: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
52
+ choices: ACCOUNT_LEVEL_CHOICES,
53
+ });
54
+ expect(yargsMock.option).toHaveBeenCalledWith('ops-level', {
55
+ type: 'string',
56
+ description: 'Operations Hub tier. Unprovided tiers default to ENTERPRISE. Choices: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
57
+ choices: ACCOUNT_LEVEL_CHOICES,
58
+ });
59
+ expect(yargsMock.option).toHaveBeenCalledWith('service-level', {
60
+ type: 'string',
61
+ description: 'Service Hub tier. Unprovided tiers default to ENTERPRISE. Choices: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
62
+ choices: ACCOUNT_LEVEL_CHOICES,
63
+ });
64
+ expect(yargsMock.option).toHaveBeenCalledWith('sales-level', {
65
+ type: 'string',
66
+ description: 'Sales Hub tier. Unprovided tiers default to ENTERPRISE. Choices: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
67
+ choices: ACCOUNT_LEVEL_CHOICES,
68
+ });
69
+ expect(yargsMock.option).toHaveBeenCalledWith('content-level', {
70
+ type: 'string',
71
+ description: 'CMS Hub tier. Unprovided tiers default to ENTERPRISE. Choices: FREE, STARTER, PROFESSIONAL, ENTERPRISE',
72
+ choices: ACCOUNT_LEVEL_CHOICES,
73
+ });
74
+ });
75
+ it('should add examples for all usage scenarios', () => {
76
+ testAccountCreateCommand.builder(yargsMock);
77
+ expect(yargsMock.example).toHaveBeenCalledWith([
78
+ [
79
+ '$0 test-account create',
80
+ 'Interactive mode - prompts for all options',
81
+ ],
82
+ [
83
+ '$0 test-account create --name "MyTestAccount"',
84
+ 'Provide name via flag, prompt for description and tier selection',
85
+ ],
86
+ [
87
+ '$0 test-account create --name "MyTestAccount" --description "Test account"',
88
+ 'Provide name and description, prompt for tier selection',
89
+ ],
90
+ [
91
+ '$0 test-account create --name "MyTestAccount" --marketing-level PROFESSIONAL',
92
+ 'Specify marketing tier, other tiers default to ENTERPRISE',
93
+ ],
94
+ [
95
+ '$0 test-account create --config-path ./test-account-config.json',
96
+ 'Create from config file (mutually exclusive with other flags)',
97
+ ],
98
+ ]);
99
+ });
32
100
  });
33
101
  });
@@ -1,6 +1,14 @@
1
+ import { AccountLevel } from '@hubspot/local-dev-lib/types/developerTestAccounts.js';
1
2
  import { CommonArgs, ConfigArgs, AccountArgs, TestingArgs, YargsCommandModule, EnvironmentArgs, JSONOutputArgs } from '../../types/Yargs.js';
2
3
  type CreateTestAccountArgs = CommonArgs & AccountArgs & ConfigArgs & TestingArgs & EnvironmentArgs & JSONOutputArgs & {
3
4
  configPath?: string;
5
+ name?: string;
6
+ description?: string;
7
+ marketingLevel?: AccountLevel;
8
+ opsLevel?: AccountLevel;
9
+ serviceLevel?: AccountLevel;
10
+ salesLevel?: AccountLevel;
11
+ contentLevel?: AccountLevel;
4
12
  };
5
13
  declare const createTestAccountCommand: YargsCommandModule<unknown, CreateTestAccountArgs>;
6
14
  export default createTestAccountCommand;
@@ -14,53 +14,83 @@ import { createDeveloperTestAccountConfigPrompt } from '../../lib/prompts/create
14
14
  import { debugError, logError } from '../../lib/errorHandlers/index.js';
15
15
  import SpinniesManager from '../../lib/ui/SpinniesManager.js';
16
16
  import { createDeveloperTestAccountV2, saveAccountToConfig, } from '../../lib/buildAccount.js';
17
+ import { ACCOUNT_LEVEL_CHOICES } from '../../lib/constants.js';
17
18
  const command = 'create';
18
19
  const describe = commands.testAccount.create.describe;
19
- async function handler(args) {
20
- const { derivedAccountId, configPath, formatOutputAsJson } = args;
21
- trackCommandUsage('test-account-create', {}, derivedAccountId);
22
- const env = getValidEnv(getEnv(derivedAccountId));
23
- let accountConfigPath = configPath;
24
- let testAccountConfig;
25
- if (!accountConfigPath) {
26
- const createTestAccountFromConfig = await listPrompt(commands.testAccount.create.createTestAccountFromConfigPrompt, {
27
- choices: [
28
- {
29
- name: commands.testAccount.create.createFromConfigOption,
30
- value: true,
31
- },
32
- {
33
- name: commands.testAccount.create.createFromScratchOption,
34
- value: false,
35
- },
36
- ],
20
+ function hasAnyFlags(args) {
21
+ const { name, description, marketingLevel, opsLevel, serviceLevel, salesLevel, contentLevel, } = args;
22
+ return !!(name ||
23
+ description ||
24
+ marketingLevel ||
25
+ opsLevel ||
26
+ serviceLevel ||
27
+ salesLevel ||
28
+ contentLevel);
29
+ }
30
+ async function readConfigFile(configPath) {
31
+ const absoluteConfigPath = path.resolve(getCwd(), configPath);
32
+ if (!fileExists(absoluteConfigPath)) {
33
+ uiLogger.error(commands.testAccount.create.errors.configFileNotFound(absoluteConfigPath));
34
+ process.exit(EXIT_CODES.ERROR);
35
+ }
36
+ try {
37
+ return JSON.parse(fs.readFileSync(absoluteConfigPath, 'utf8'));
38
+ }
39
+ catch (err) {
40
+ uiLogger.error(commands.testAccount.create.errors.configFileParseFailed(absoluteConfigPath));
41
+ process.exit(EXIT_CODES.ERROR);
42
+ }
43
+ }
44
+ async function promptForConfigPath() {
45
+ const createTestAccountFromConfig = await listPrompt(commands.testAccount.create.createTestAccountFromConfigPrompt, {
46
+ choices: [
47
+ {
48
+ name: commands.testAccount.create.createFromConfigOption,
49
+ value: true,
50
+ },
51
+ {
52
+ name: commands.testAccount.create.createFromScratchOption,
53
+ value: false,
54
+ },
55
+ ],
56
+ });
57
+ if (createTestAccountFromConfig) {
58
+ const configPathPromptResult = await promptUser({
59
+ name: 'configPath',
60
+ message: commands.testAccount.create.configPathPrompt,
61
+ type: 'input',
37
62
  });
38
- if (createTestAccountFromConfig) {
39
- const configPathPromptResult = await promptUser({
40
- name: 'configPath',
41
- message: commands.testAccount.create.configPathPrompt,
42
- type: 'input',
43
- });
44
- accountConfigPath = configPathPromptResult.configPath;
45
- }
63
+ return configPathPromptResult.configPath;
46
64
  }
47
- if (accountConfigPath) {
48
- const absoluteConfigPath = path.resolve(getCwd(), accountConfigPath);
49
- if (!fileExists(absoluteConfigPath)) {
50
- uiLogger.error(commands.testAccount.create.errors.configFileNotFound(absoluteConfigPath));
51
- process.exit(EXIT_CODES.ERROR);
52
- }
53
- try {
54
- testAccountConfig = JSON.parse(fs.readFileSync(absoluteConfigPath, 'utf8'));
55
- }
56
- catch (err) {
57
- uiLogger.error(commands.testAccount.create.errors.configFileParseFailed(absoluteConfigPath));
58
- process.exit(EXIT_CODES.ERROR);
59
- }
65
+ return undefined;
66
+ }
67
+ async function buildTestAccountConfig(args) {
68
+ const { configPath, name, description, marketingLevel, opsLevel, serviceLevel, salesLevel, contentLevel, } = args;
69
+ if (configPath) {
70
+ return readConfigFile(configPath);
60
71
  }
61
- else {
62
- testAccountConfig = await createDeveloperTestAccountConfigPrompt();
72
+ let accountConfigPath;
73
+ if (!hasAnyFlags(args)) {
74
+ accountConfigPath = await promptForConfigPath();
75
+ }
76
+ if (accountConfigPath) {
77
+ return readConfigFile(accountConfigPath);
63
78
  }
79
+ return createDeveloperTestAccountConfigPrompt({
80
+ name,
81
+ description,
82
+ marketingLevel,
83
+ opsLevel,
84
+ serviceLevel,
85
+ salesLevel,
86
+ contentLevel,
87
+ });
88
+ }
89
+ async function handler(args) {
90
+ const { derivedAccountId, formatOutputAsJson } = args;
91
+ trackCommandUsage('test-account-create', {}, derivedAccountId);
92
+ const env = getValidEnv(getEnv(derivedAccountId));
93
+ const testAccountConfig = await buildTestAccountConfig(args);
64
94
  const resultJson = {};
65
95
  SpinniesManager.init({
66
96
  succeedColor: 'white',
@@ -90,7 +120,12 @@ async function handler(args) {
90
120
  else {
91
121
  // Only save to config if not using json output
92
122
  try {
93
- await saveAccountToConfig(resultJson.accountId, testAccountConfig.accountName, env, resultJson.personalAccessKey);
123
+ const savedAccountName = await saveAccountToConfig(resultJson.accountId, testAccountConfig.accountName, env, resultJson.personalAccessKey);
124
+ // Inform user if the account name was normalized
125
+ if (savedAccountName !== testAccountConfig.accountName) {
126
+ uiLogger.log('');
127
+ uiLogger.info(commands.testAccount.create.savedAccountNameDiffers(testAccountConfig.accountName, savedAccountName));
128
+ }
94
129
  }
95
130
  catch (e) {
96
131
  debugError(e);
@@ -105,10 +140,65 @@ function createTestAccountBuilder(yargs) {
105
140
  type: 'string',
106
141
  description: commands.testAccount.create.options.configPath,
107
142
  });
143
+ yargs.option('name', {
144
+ type: 'string',
145
+ description: commands.testAccount.create.options.accountName,
146
+ });
147
+ yargs.option('description', {
148
+ type: 'string',
149
+ description: commands.testAccount.create.options.description,
150
+ });
151
+ yargs.option('marketing-level', {
152
+ type: 'string',
153
+ description: commands.testAccount.create.options.marketingLevel,
154
+ choices: ACCOUNT_LEVEL_CHOICES,
155
+ });
156
+ yargs.option('ops-level', {
157
+ type: 'string',
158
+ description: commands.testAccount.create.options.opsLevel,
159
+ choices: ACCOUNT_LEVEL_CHOICES,
160
+ });
161
+ yargs.option('service-level', {
162
+ type: 'string',
163
+ description: commands.testAccount.create.options.serviceLevel,
164
+ choices: ACCOUNT_LEVEL_CHOICES,
165
+ });
166
+ yargs.option('sales-level', {
167
+ type: 'string',
168
+ description: commands.testAccount.create.options.salesLevel,
169
+ choices: ACCOUNT_LEVEL_CHOICES,
170
+ });
171
+ yargs.option('content-level', {
172
+ type: 'string',
173
+ description: commands.testAccount.create.options.contentLevel,
174
+ choices: ACCOUNT_LEVEL_CHOICES,
175
+ });
176
+ yargs.conflicts('config-path', [
177
+ 'name',
178
+ 'description',
179
+ 'marketing-level',
180
+ 'ops-level',
181
+ 'service-level',
182
+ 'sales-level',
183
+ 'content-level',
184
+ ]);
108
185
  yargs.example([
186
+ ['$0 test-account create', 'Interactive mode - prompts for all options'],
187
+ [
188
+ '$0 test-account create --name "MyTestAccount"',
189
+ 'Provide name via flag, prompt for description and tier selection',
190
+ ],
191
+ [
192
+ '$0 test-account create --name "MyTestAccount" --description "Test account"',
193
+ 'Provide name and description, prompt for tier selection',
194
+ ],
195
+ [
196
+ '$0 test-account create --name "MyTestAccount" --marketing-level PROFESSIONAL',
197
+ 'Specify marketing tier, other tiers default to ENTERPRISE',
198
+ ],
109
199
  [
110
- '$0 create --config-path ./test-account-config.json',
111
- commands.testAccount.create.example('./test-account-config.json'),
200
+ '$0 test-account create --config-path ./test-account-config.json',
201
+ 'Create from config file (mutually exclusive with other flags)',
112
202
  ],
113
203
  ]);
114
204
  return yargs;
@@ -1,6 +1,6 @@
1
1
  import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, YargsCommandModule } from '../../types/Yargs.js';
2
2
  export declare const command = "import-data";
3
- export declare const describe: "Import data into the CRM";
3
+ export declare const describe: string;
4
4
  type CrmImportDataArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & {
5
5
  filePath: string | undefined;
6
6
  skipConfirm: boolean | undefined;