@hubspot/cli 7.8.12-experimental.0 → 7.8.12-experimental.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 (244) hide show
  1. package/bin/cli.js +31 -25
  2. package/commands/__tests__/auth.test.js +5 -0
  3. package/commands/__tests__/doctor.test.js +16 -16
  4. package/commands/account/clean.js +18 -27
  5. package/commands/account/createOverride.js +13 -31
  6. package/commands/account/info.js +20 -31
  7. package/commands/account/list.js +16 -22
  8. package/commands/account/remove.js +12 -20
  9. package/commands/account/removeOverride.js +11 -21
  10. package/commands/account/rename.js +6 -9
  11. package/commands/account/use.js +12 -26
  12. package/commands/account.js +2 -2
  13. package/commands/app/__tests__/migrate.test.js +5 -5
  14. package/commands/app/migrate.js +13 -18
  15. package/commands/app.js +1 -6
  16. package/commands/auth.d.ts +1 -0
  17. package/commands/auth.js +16 -7
  18. package/commands/cms/convertFields.js +7 -9
  19. package/commands/cms/getReactModule.js +9 -14
  20. package/commands/cms/lighthouseScore.js +33 -36
  21. package/commands/cms.js +2 -2
  22. package/commands/completion.js +3 -3
  23. package/commands/config/set.d.ts +1 -1
  24. package/commands/config/set.js +64 -36
  25. package/commands/config.js +2 -2
  26. package/commands/create.js +2 -2
  27. package/commands/customObject/create.js +10 -12
  28. package/commands/customObject/schema/create.js +9 -11
  29. package/commands/customObject/schema/delete.js +16 -16
  30. package/commands/customObject/schema/fetch-all.js +12 -11
  31. package/commands/customObject/schema/fetch.js +15 -15
  32. package/commands/customObject/schema/list.js +4 -4
  33. package/commands/customObject/schema/update.js +13 -13
  34. package/commands/customObject/schema.js +2 -2
  35. package/commands/customObject.js +6 -7
  36. package/commands/doctor.js +8 -11
  37. package/commands/feedback.js +6 -11
  38. package/commands/fetch.js +8 -8
  39. package/commands/filemanager/fetch.js +7 -7
  40. package/commands/filemanager/upload.js +15 -34
  41. package/commands/filemanager.js +2 -2
  42. package/commands/function/deploy.js +11 -29
  43. package/commands/function/list.js +8 -8
  44. package/commands/function/server.js +9 -11
  45. package/commands/function.d.ts +1 -1
  46. package/commands/function.js +2 -2
  47. package/commands/getStarted.js +2 -2
  48. package/commands/hubdb/clear.js +7 -15
  49. package/commands/hubdb/create.js +9 -15
  50. package/commands/hubdb/delete.js +8 -15
  51. package/commands/hubdb/fetch.js +6 -9
  52. package/commands/hubdb.d.ts +1 -1
  53. package/commands/hubdb.js +2 -2
  54. package/commands/init.js +2 -3
  55. package/commands/lint.js +16 -16
  56. package/commands/list.js +8 -14
  57. package/commands/logs.js +14 -20
  58. package/commands/mv.js +6 -17
  59. package/commands/open.js +5 -5
  60. package/commands/project/__tests__/add.test.js +4 -2
  61. package/commands/project/__tests__/deploy.test.js +3 -4
  62. package/commands/project/__tests__/installDeps.test.js +8 -8
  63. package/commands/project/__tests__/logs.test.js +1 -1
  64. package/commands/project/__tests__/migrate.test.js +5 -5
  65. package/commands/project/__tests__/migrateApp.test.js +2 -5
  66. package/commands/project/__tests__/validate.test.js +98 -0
  67. package/commands/project/add.js +3 -3
  68. package/commands/project/cloneApp.js +14 -19
  69. package/commands/project/create.js +0 -1
  70. package/commands/project/deploy.js +3 -3
  71. package/commands/project/dev/deprecatedFlow.js +7 -16
  72. package/commands/project/dev/index.js +14 -12
  73. package/commands/project/dev/unifiedFlow.js +3 -1
  74. package/commands/project/download.js +10 -13
  75. package/commands/project/installDeps.js +8 -8
  76. package/commands/project/listBuilds.js +11 -20
  77. package/commands/project/logs.js +21 -24
  78. package/commands/project/migrateApp.js +9 -15
  79. package/commands/project/open.js +6 -13
  80. package/commands/project/upload.d.ts +2 -2
  81. package/commands/project/upload.js +17 -26
  82. package/commands/project/validate.js +6 -6
  83. package/commands/project/watch.js +13 -22
  84. package/commands/project.js +2 -2
  85. package/commands/sandbox/__tests__/create.test.js +5 -5
  86. package/commands/sandbox/create.js +22 -32
  87. package/commands/sandbox/delete.js +38 -63
  88. package/commands/sandbox.js +2 -2
  89. package/commands/secret/addSecret.js +7 -17
  90. package/commands/secret/deleteSecret.js +10 -20
  91. package/commands/secret/listSecret.js +8 -10
  92. package/commands/secret/updateSecret.js +9 -17
  93. package/commands/secret.js +2 -2
  94. package/commands/testAccount/__tests__/delete.test.js +2 -4
  95. package/commands/testAccount/create.js +0 -3
  96. package/commands/testAccount/delete.d.ts +4 -3
  97. package/commands/testAccount/delete.js +155 -14
  98. package/commands/theme/preview.js +1 -4
  99. package/lang/en.d.ts +310 -124
  100. package/lang/en.js +351 -169
  101. package/lang/en.lyaml +2 -2
  102. package/lib/__tests__/buildAccount.test.js +2 -1
  103. package/lib/__tests__/commonOpts.test.js +1 -1
  104. package/lib/__tests__/dependencyManagement.test.js +1 -1
  105. package/lib/__tests__/developerTestAccounts.test.js +3 -3
  106. package/lib/__tests__/npm.test.js +1 -1
  107. package/lib/__tests__/oauth.test.js +4 -4
  108. package/lib/__tests__/process.test.js +10 -5
  109. package/lib/__tests__/sandboxSync.test.js +8 -8
  110. package/lib/__tests__/sandboxes.test.js +8 -8
  111. package/lib/__tests__/serverlessLogs.test.js +1 -1
  112. package/lib/__tests__/usageTracking.test.js +5 -5
  113. package/lib/__tests__/validation.test.js +2 -1
  114. package/lib/__tests__/yargsUtils.test.js +83 -9
  115. package/lib/app/__tests__/migrate.test.js +5 -5
  116. package/lib/app/__tests__/migrate_legacy.test.js +1 -1
  117. package/lib/app/migrate.js +1 -1
  118. package/lib/app/migrate_legacy.js +20 -24
  119. package/lib/buildAccount.js +25 -57
  120. package/lib/commonOpts.d.ts +1 -1
  121. package/lib/commonOpts.js +25 -22
  122. package/lib/configOptions.js +7 -0
  123. package/lib/constants.d.ts +6 -1
  124. package/lib/constants.js +10 -1
  125. package/lib/dependencyManagement.js +9 -27
  126. package/lib/developerTestAccounts.js +9 -23
  127. package/lib/doctor/Diagnosis.js +11 -23
  128. package/lib/doctor/DiagnosticInfoBuilder.js +12 -11
  129. package/lib/doctor/Doctor.js +42 -90
  130. package/lib/doctor/__tests__/Doctor.test.js +4 -4
  131. package/lib/errorHandlers/index.js +12 -20
  132. package/lib/errorHandlers/suppressError.js +11 -18
  133. package/lib/lang.js +6 -5
  134. package/lib/links.js +4 -4
  135. package/lib/middleware/__test__/commandTargetingUtils.test.js +99 -0
  136. package/lib/middleware/__test__/configMiddleware.test.js +11 -11
  137. package/lib/middleware/__test__/yargsChecksMiddleware.test.js +6 -8
  138. package/lib/middleware/commandTargetingUtils.d.ts +8 -0
  139. package/lib/middleware/commandTargetingUtils.js +78 -0
  140. package/lib/middleware/configMiddleware.d.ts +1 -1
  141. package/lib/middleware/configMiddleware.js +21 -81
  142. package/lib/middleware/gitMiddleware.js +5 -1
  143. package/lib/middleware/notificationsMiddleware.js +5 -11
  144. package/lib/middleware/yargsChecksMiddleware.js +6 -9
  145. package/lib/npm.js +2 -2
  146. package/lib/oauth.js +5 -5
  147. package/lib/process.js +5 -4
  148. package/lib/projectProfiles.d.ts +1 -1
  149. package/lib/projectProfiles.js +2 -10
  150. package/lib/projects/__tests__/AppDevModeInterface.test.js +14 -34
  151. package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +70 -39
  152. package/lib/projects/__tests__/localDevProjectHelpers.test.js +2 -0
  153. package/lib/projects/__tests__/platformVersion.test.js +8 -8
  154. package/lib/projects/__tests__/projects.test.js +12 -12
  155. package/lib/projects/__tests__/structure.test.js +3 -3
  156. package/lib/projects/__tests__/upload.test.d.ts +1 -0
  157. package/lib/projects/__tests__/upload.test.js +82 -0
  158. package/lib/projects/add/__tests__/legacyAddComponent.test.js +6 -6
  159. package/lib/projects/add/__tests__/v3AddComponent.test.js +4 -4
  160. package/lib/projects/create/__tests__/legacy.test.js +5 -5
  161. package/lib/projects/create/__tests__/v3.test.js +1 -1
  162. package/lib/projects/create/index.js +2 -2
  163. package/lib/projects/create/legacy.js +2 -2
  164. package/lib/projects/create/v3.js +2 -2
  165. package/lib/projects/localDev/AppDevModeInterface.d.ts +2 -0
  166. package/lib/projects/localDev/AppDevModeInterface.js +22 -20
  167. package/lib/projects/localDev/LocalDevLogger.js +10 -11
  168. package/lib/projects/localDev/LocalDevManager.js +4 -5
  169. package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +0 -1
  170. package/lib/projects/localDev/LocalDevWebsocketServer.js +7 -10
  171. package/lib/projects/localDev/helpers/project.d.ts +1 -0
  172. package/lib/projects/localDev/helpers/project.js +37 -0
  173. package/lib/projects/platformVersion.d.ts +1 -1
  174. package/lib/projects/platformVersion.js +1 -1
  175. package/lib/projects/structure.d.ts +2 -2
  176. package/lib/projects/structure.js +6 -6
  177. package/lib/projects/upload.d.ts +2 -3
  178. package/lib/projects/upload.js +17 -9
  179. package/lib/prompts/__tests__/downloadProjectPrompt.test.js +1 -0
  180. package/lib/prompts/accountNamePrompt.js +14 -19
  181. package/lib/prompts/accountsPrompt.js +2 -2
  182. package/lib/prompts/cmsFieldPrompt.js +2 -2
  183. package/lib/prompts/createApiSamplePrompt.js +5 -5
  184. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +10 -1
  185. package/lib/prompts/createFunctionPrompt.js +14 -14
  186. package/lib/prompts/createModulePrompt.js +9 -9
  187. package/lib/prompts/createTemplatePrompt.js +2 -2
  188. package/lib/prompts/downloadProjectPrompt.js +5 -8
  189. package/lib/prompts/personalAccessKeyPrompt.js +3 -3
  190. package/lib/prompts/previewPrompt.js +6 -6
  191. package/lib/prompts/projectAddPrompt.js +6 -0
  192. package/lib/prompts/projectDevTargetAccountPrompt.js +20 -32
  193. package/lib/prompts/projectNamePrompt.js +4 -8
  194. package/lib/prompts/projectsLogsPrompt.js +2 -4
  195. package/lib/prompts/promptUtils.js +27 -9
  196. package/lib/prompts/sandboxesPrompt.js +7 -7
  197. package/lib/prompts/secretPrompt.js +3 -3
  198. package/lib/prompts/selectAppPrompt.js +3 -3
  199. package/lib/prompts/selectHubDBTablePrompt.js +9 -13
  200. package/lib/prompts/selectPublicAppForMigrationPrompt.js +15 -19
  201. package/lib/prompts/setAsDefaultAccountPrompt.js +4 -8
  202. package/lib/prompts/uploadPrompt.js +5 -5
  203. package/lib/sandboxSync.js +24 -41
  204. package/lib/sandboxes.js +19 -47
  205. package/lib/schema.js +3 -3
  206. package/lib/serverlessLogs.js +11 -13
  207. package/lib/theme/__tests__/migrate.test.js +3 -3
  208. package/lib/theme/migrate.js +2 -2
  209. package/lib/ui/SpinniesManager.d.ts +2 -0
  210. package/lib/ui/SpinniesManager.js +7 -0
  211. package/lib/ui/boxen.js +1 -2
  212. package/lib/ui/git.js +13 -10
  213. package/lib/ui/index.d.ts +4 -0
  214. package/lib/ui/index.js +47 -38
  215. package/lib/ui/serverlessFunctionLogs.js +9 -7
  216. package/lib/ui/uiMessages.d.ts +68 -0
  217. package/lib/ui/uiMessages.js +71 -0
  218. package/lib/usageTracking.js +7 -7
  219. package/lib/validation.js +20 -23
  220. package/lib/yargsUtils.d.ts +1 -1
  221. package/lib/yargsUtils.js +12 -5
  222. package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +2 -2
  223. package/mcp-server/tools/index.js +4 -0
  224. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +23 -0
  225. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +68 -0
  226. package/mcp-server/tools/project/GetApplicationInfoTool.d.ts +11 -0
  227. package/mcp-server/tools/project/GetApplicationInfoTool.js +49 -0
  228. package/mcp-server/tools/project/GetConfigValuesTool.js +2 -2
  229. package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +2 -2
  230. package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.d.ts +1 -0
  231. package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +169 -0
  232. package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.d.ts +1 -0
  233. package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +115 -0
  234. package/mcp-server/utils/toolUsageTracking.js +2 -2
  235. package/package.json +6 -6
  236. package/types/Yargs.d.ts +1 -1
  237. package/commands/app/__tests__/install.test.js +0 -47
  238. package/commands/app/install.d.ts +0 -8
  239. package/commands/app/install.js +0 -122
  240. package/lib/middleware/__test__/utils.test.js +0 -51
  241. package/lib/middleware/utils.d.ts +0 -8
  242. package/lib/middleware/utils.js +0 -14
  243. /package/commands/{app/__tests__/install.test.d.ts → project/__tests__/validate.test.d.ts} +0 -0
  244. /package/lib/middleware/__test__/{utils.test.d.ts → commandTargetingUtils.test.d.ts} +0 -0
@@ -0,0 +1,115 @@
1
+ import { GetApplicationInfoTool } from '../GetApplicationInfoTool.js';
2
+ import { getAccountId } from '@hubspot/local-dev-lib/config';
3
+ import { http } from '@hubspot/local-dev-lib/http';
4
+ import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
5
+ vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
6
+ vi.mock('../../utils/toolUsageTracking');
7
+ vi.mock('@hubspot/local-dev-lib/http');
8
+ vi.mock('@hubspot/local-dev-lib/errors/index');
9
+ vi.mock('@hubspot/local-dev-lib/config');
10
+ const mockGetAccountId = getAccountId;
11
+ const mockHttp = http;
12
+ const mockIsHubSpotHttpError = isHubSpotHttpError;
13
+ describe('mcp-server/tools/project/GetApplicationInfoTool', () => {
14
+ let mockMcpServer;
15
+ let tool;
16
+ let mockRegisteredTool;
17
+ beforeEach(() => {
18
+ vi.clearAllMocks();
19
+ // @ts-expect-error Not mocking the whole thing
20
+ mockMcpServer = {
21
+ registerTool: vi.fn(),
22
+ };
23
+ mockRegisteredTool = {};
24
+ mockMcpServer.registerTool.mockReturnValue(mockRegisteredTool);
25
+ tool = new GetApplicationInfoTool(mockMcpServer);
26
+ });
27
+ describe('register', () => {
28
+ it('should register tool with correct parameters', () => {
29
+ const result = tool.register();
30
+ expect(mockMcpServer.registerTool).toHaveBeenCalledWith('get-applications-info', {
31
+ title: 'Get Applications Information',
32
+ description: 'Retrieves a list of all HubSpot applications available in the current account. Returns an array of applications, where each application contains an appId (numeric identifier) and appName (string). This information is useful for identifying available applications before using other tools that require specific application IDs, such as getting API usage patterns. No input parameters are required - this tool fetches all applications from the HubSpot Insights API.',
33
+ inputSchema: {},
34
+ }, tool.handler);
35
+ expect(result).toBe(mockRegisteredTool);
36
+ });
37
+ });
38
+ describe('handler', () => {
39
+ const input = {};
40
+ beforeEach(() => {
41
+ mockGetAccountId.mockReturnValue(123456789);
42
+ mockIsHubSpotHttpError.mockReturnValue(false);
43
+ });
44
+ it('should return application information successfully', async () => {
45
+ const mockResponse = {
46
+ data: {
47
+ applications: [
48
+ {
49
+ appId: 12345,
50
+ appName: 'Test App 1',
51
+ },
52
+ {
53
+ appId: 67890,
54
+ appName: 'Test App 2',
55
+ },
56
+ ],
57
+ },
58
+ status: 200,
59
+ statusText: 'OK',
60
+ headers: {},
61
+ config: { headers: {} },
62
+ };
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ mockHttp.get.mockResolvedValue(mockResponse);
65
+ const result = await tool.handler(input);
66
+ expect(mockGetAccountId).toHaveBeenCalledWith();
67
+ expect(mockHttp.get).toHaveBeenCalledWith(123456789, {
68
+ url: 'app/feature/utilization/public/v3/insights/apps',
69
+ });
70
+ expect(result).toEqual({
71
+ content: [
72
+ {
73
+ type: 'text',
74
+ text: JSON.stringify(mockResponse.data, null, 2),
75
+ },
76
+ ],
77
+ });
78
+ });
79
+ it('should return error when account ID cannot be determined', async () => {
80
+ mockGetAccountId.mockReturnValue(null);
81
+ const result = await tool.handler(input);
82
+ expect(result).toEqual({
83
+ content: [
84
+ {
85
+ type: 'text',
86
+ text: 'No account ID found. Please run `hs account auth` to configure an account, or set a default account with `hs account use <account>`',
87
+ },
88
+ ],
89
+ });
90
+ expect(mockHttp.get).not.toHaveBeenCalled();
91
+ });
92
+ it('should handle empty applications response', async () => {
93
+ const mockResponse = {
94
+ data: {
95
+ applications: [],
96
+ },
97
+ status: 200,
98
+ statusText: 'OK',
99
+ headers: {},
100
+ config: { headers: {} },
101
+ };
102
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
+ mockHttp.get.mockResolvedValue(mockResponse);
104
+ const result = await tool.handler(input);
105
+ expect(result).toEqual({
106
+ content: [
107
+ {
108
+ type: 'text',
109
+ text: JSON.stringify(mockResponse.data, null, 2),
110
+ },
111
+ ],
112
+ });
113
+ });
114
+ });
115
+ });
@@ -1,7 +1,7 @@
1
1
  import { trackUsage } from '@hubspot/local-dev-lib/trackUsage';
2
- import { logger } from '@hubspot/local-dev-lib/logger';
3
2
  import { EventClass, getNodeVersionData, getPlatform, } from '../../lib/usageTracking.js';
4
3
  import { getAccountId, isTrackingAllowed } from '@hubspot/local-dev-lib/config';
4
+ import { uiLogger } from '../../lib/ui/logger.js';
5
5
  export async function trackToolUsage(toolName, meta) {
6
6
  if (!isTrackingAllowed()) {
7
7
  return;
@@ -16,7 +16,7 @@ export async function trackToolUsage(toolName, meta) {
16
16
  };
17
17
  const accountId = getAccountId() || undefined;
18
18
  try {
19
- logger.info('Tracking tool usage');
19
+ uiLogger.info('Tracking tool usage');
20
20
  await trackUsage('cli-interaction', EventClass.INTERACTION, usageTrackingEvent, accountId);
21
21
  }
22
22
  catch (error) { }
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "7.8.12-experimental.0",
3
+ "version": "7.8.12-experimental.1",
4
4
  "description": "The official CLI for developing on HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "https://github.com/HubSpot/hubspot-cli",
7
7
  "type": "module",
8
8
  "dependencies": {
9
- "@hubspot/local-dev-lib": "3.19.1",
10
- "@hubspot/project-parsing-lib": "0.8.6",
9
+ "@hubspot/local-dev-lib": "3.20.0",
10
+ "@hubspot/project-parsing-lib": "0.10.0-beta.0",
11
11
  "@hubspot/serverless-dev-runtime": "7.0.6",
12
12
  "@hubspot/theme-preview-dev-server": "0.0.10",
13
- "@hubspot/ui-extensions-dev-server": "0.10.0",
13
+ "@hubspot/ui-extensions-dev-server": "0.10.1",
14
14
  "archiver": "7.0.1",
15
15
  "boxen": "8.0.1",
16
16
  "chalk": "5.4.1",
@@ -29,7 +29,7 @@
29
29
  "react": "^18.0.0",
30
30
  "strip-ansi": "7.1.0",
31
31
  "table": "6.9.0",
32
- "tmp": "0.2.3",
32
+ "tmp": "0.2.4",
33
33
  "update-notifier": "7.3.1",
34
34
  "ws": "^8.18.2",
35
35
  "yargs": "17.7.2",
@@ -52,7 +52,7 @@
52
52
  "@types/yargs": "^17.0.33",
53
53
  "@typescript-eslint/eslint-plugin": "^8.30.1",
54
54
  "@typescript-eslint/parser": "^8.11.0",
55
- "axios": "^1.7.4",
55
+ "axios": "^1.12.2",
56
56
  "eslint": "^8.56.0",
57
57
  "eslint-plugin-import": "^2.31.0",
58
58
  "husky": "^4.3.8",
package/types/Yargs.d.ts CHANGED
@@ -15,7 +15,7 @@ export type AccountArgs = {
15
15
  account?: string;
16
16
  };
17
17
  export type EnvironmentArgs = {
18
- 'use-env'?: boolean;
18
+ 'use-env'?: string;
19
19
  };
20
20
  export type OverwriteArgs = Options & {
21
21
  o?: boolean;
@@ -1,47 +0,0 @@
1
- import yargs from 'yargs';
2
- import { addAccountOptions, addConfigOptions, addUseEnvironmentOptions, addGlobalOptions, addJSONOutputOptions, } from '../../../lib/commonOpts.js';
3
- import installCommand from '../install.js';
4
- vi.mock('../../../lib/commonOpts');
5
- describe('commands/app/install', () => {
6
- const yargsMock = yargs;
7
- describe('command', () => {
8
- it('should have the correct command structure', () => {
9
- expect(installCommand.command).toEqual('install <test-account-id>');
10
- });
11
- });
12
- describe('describe', () => {
13
- it('should provide a description', () => {
14
- expect(installCommand.describe).not.toBeDefined();
15
- });
16
- });
17
- describe('builder', () => {
18
- it('should support the correct options', () => {
19
- installCommand.builder(yargsMock);
20
- expect(addGlobalOptions).toHaveBeenCalledTimes(1);
21
- expect(addGlobalOptions).toHaveBeenCalledWith(yargsMock);
22
- expect(addAccountOptions).toHaveBeenCalledTimes(1);
23
- expect(addAccountOptions).toHaveBeenCalledWith(yargsMock);
24
- expect(addConfigOptions).toHaveBeenCalledTimes(1);
25
- expect(addConfigOptions).toHaveBeenCalledWith(yargsMock);
26
- expect(addUseEnvironmentOptions).toHaveBeenCalledTimes(1);
27
- expect(addUseEnvironmentOptions).toHaveBeenCalledWith(yargsMock);
28
- expect(addJSONOutputOptions).toHaveBeenCalledTimes(1);
29
- expect(addJSONOutputOptions).toHaveBeenCalledWith(yargsMock);
30
- expect(yargsMock.positional).toHaveBeenCalledTimes(1);
31
- expect(yargsMock.positional).toHaveBeenCalledWith('test-account-id', expect.objectContaining({
32
- type: 'number',
33
- required: true,
34
- describe: expect.any(String),
35
- }));
36
- expect(yargsMock.option).toHaveBeenCalledTimes(2);
37
- expect(yargsMock.option).toHaveBeenCalledWith('app-uid', expect.objectContaining({
38
- type: 'string',
39
- describe: expect.any(String),
40
- }));
41
- expect(yargsMock.option).toHaveBeenCalledWith('project-name', expect.objectContaining({
42
- type: 'string',
43
- describe: expect.any(String),
44
- }));
45
- });
46
- });
47
- });
@@ -1,8 +0,0 @@
1
- import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModule, JSONOutputArgs } from '../../types/Yargs.js';
2
- type InstallAppArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs & {
3
- appUid?: string;
4
- projectName?: string;
5
- testAccountId: number;
6
- };
7
- declare const installAppCommand: YargsCommandModule<unknown, InstallAppArgs>;
8
- export default installAppCommand;
@@ -1,122 +0,0 @@
1
- import { fetchDeveloperTestAccountOauthAppInstallStatus, installOauthAppIntoDeveloperTestAccount, } from '@hubspot/local-dev-lib/api/developerTestAccounts';
2
- import { trackCommandUsage } from '../../lib/usageTracking.js';
3
- import { commands } from '../../lang/en.js';
4
- import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
5
- import { makeYargsBuilder } from '../../lib/yargsUtils.js';
6
- import { APP_AUTH_TYPES } from '../../lib/constants.js';
7
- import { uiLogger } from '../../lib/ui/logger.js';
8
- import SpinniesManager from '../../lib/ui/SpinniesManager.js';
9
- import { poll } from '../../lib/polling.js';
10
- import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
11
- import { handleTranslate } from '../../lib/projects/upload.js';
12
- import { isAppIRNode } from '../../lib/projects/structure.js';
13
- import { logError } from '../../lib/errorHandlers/index.js';
14
- const command = 'install <test-account-id>';
15
- const describe = undefined; // commands.app.subcommands.install.describe;
16
- async function handler(args) {
17
- const { derivedAccountId, appUid, projectName, testAccountId, formatOutputAsJson, } = args;
18
- trackCommandUsage('app-install', {}, derivedAccountId);
19
- const jsonOutput = {};
20
- let targetProjectName = projectName;
21
- let targetAppUid = appUid;
22
- const { projectConfig, projectDir } = await getProjectConfig();
23
- if (!targetProjectName) {
24
- validateProjectConfig(projectConfig, projectDir);
25
- targetProjectName = projectConfig?.name;
26
- }
27
- if (!targetProjectName) {
28
- uiLogger.error(commands.app.subcommands.install.errors.mustSpecifyProjectName);
29
- process.exit(EXIT_CODES.ERROR);
30
- }
31
- let isAppOauth = true;
32
- if (!targetAppUid) {
33
- const intermediateRepresentation = await handleTranslate(projectDir, projectConfig, derivedAccountId, true, undefined);
34
- if (intermediateRepresentation) {
35
- Object.values(intermediateRepresentation.intermediateNodesIndexedByUid).forEach(node => {
36
- if (isAppIRNode(node)) {
37
- targetAppUid = node.uid;
38
- isAppOauth = node.config.auth.type === APP_AUTH_TYPES.OAUTH;
39
- }
40
- });
41
- }
42
- }
43
- if (!targetAppUid) {
44
- uiLogger.error(commands.app.subcommands.install.errors.noAppUidFound);
45
- process.exit(EXIT_CODES.ERROR);
46
- }
47
- if (!isAppOauth) {
48
- uiLogger.error(commands.app.subcommands.install.errors.appMustBeOauth);
49
- process.exit(EXIT_CODES.ERROR);
50
- }
51
- try {
52
- const { data } = await installOauthAppIntoDeveloperTestAccount(derivedAccountId, testAccountId, targetProjectName, targetAppUid);
53
- if (data?.authCodes.length > 0) {
54
- jsonOutput.authCode = data.authCodes[0].authCode;
55
- }
56
- }
57
- catch (err) {
58
- logError(err);
59
- process.exit(EXIT_CODES.ERROR);
60
- }
61
- SpinniesManager.init({
62
- succeedColor: 'white',
63
- });
64
- SpinniesManager.add('installApp', {
65
- text: commands.app.subcommands.install.polling.start,
66
- });
67
- let appInstallSucceeded = false;
68
- try {
69
- await poll(() => fetchDeveloperTestAccountOauthAppInstallStatus(derivedAccountId, targetProjectName, targetAppUid), {
70
- successStates: ['SUCCESS'],
71
- errorStates: [],
72
- });
73
- appInstallSucceeded = true;
74
- }
75
- catch (err) {
76
- SpinniesManager.fail('installApp');
77
- logError(err);
78
- process.exit(EXIT_CODES.ERROR);
79
- }
80
- if (!appInstallSucceeded) {
81
- SpinniesManager.fail('installApp');
82
- process.exit(EXIT_CODES.ERROR);
83
- }
84
- SpinniesManager.succeed('installApp', {
85
- text: commands.app.subcommands.install.polling.success,
86
- });
87
- if (formatOutputAsJson) {
88
- uiLogger.json(jsonOutput);
89
- }
90
- process.exit(EXIT_CODES.SUCCESS);
91
- }
92
- function installAppBuilder(yargs) {
93
- yargs.positional('test-account-id', {
94
- describe: commands.app.subcommands.install.positionals.testAccountId,
95
- required: true,
96
- type: 'number',
97
- });
98
- yargs.option('app-uid', {
99
- describe: commands.app.subcommands.install.options.appUid,
100
- type: 'string',
101
- });
102
- yargs.option('project-name', {
103
- describe: commands.app.subcommands.install.options.projectName,
104
- type: 'string',
105
- });
106
- yargs.example('install 1234567890 --app-uid=my-app-uid --project-name=my-project', commands.app.subcommands.install.example);
107
- return yargs;
108
- }
109
- const builder = makeYargsBuilder(installAppBuilder, command, commands.app.subcommands.install.describe, {
110
- useGlobalOptions: true,
111
- useAccountOptions: true,
112
- useConfigOptions: true,
113
- useEnvironmentOptions: true,
114
- useJSONOutputOptions: true,
115
- });
116
- const installAppCommand = {
117
- command,
118
- describe,
119
- handler,
120
- builder,
121
- };
122
- export default installAppCommand;
@@ -1,51 +0,0 @@
1
- import { isTargetedCommand } from '../utils.js';
2
- const targetCommandMap = {
3
- init: { target: true },
4
- account: {
5
- target: true,
6
- subCommands: {
7
- use: { target: true },
8
- },
9
- },
10
- project: {
11
- subCommands: {
12
- deploy: { target: true },
13
- },
14
- },
15
- };
16
- describe('lib/middleware/utils', () => {
17
- describe('isTargetedCommand()', () => {
18
- it('should return true for a direct target command', () => {
19
- const result = isTargetedCommand(['init'], targetCommandMap);
20
- expect(result).toBe(true);
21
- });
22
- it('should return true for a command with a subcommand', () => {
23
- const result = isTargetedCommand(['account'], targetCommandMap);
24
- expect(result).toBe(true);
25
- });
26
- it('should return true for a nested target command', () => {
27
- const result = isTargetedCommand(['project', 'deploy'], targetCommandMap);
28
- expect(result).toBe(true);
29
- });
30
- it('should return false for a non-existent command', () => {
31
- const result = isTargetedCommand(['nonexistent'], targetCommandMap);
32
- expect(result).toBe(false);
33
- });
34
- it('should return false for a non-targeted command', () => {
35
- const result = isTargetedCommand(['auth'], targetCommandMap);
36
- expect(result).toBe(false);
37
- });
38
- it('should return false for a command with a targeted subcommand', () => {
39
- const result = isTargetedCommand(['project'], targetCommandMap);
40
- expect(result).toBe(false);
41
- });
42
- it('should return false for a non-existent subcommand', () => {
43
- const result = isTargetedCommand(['auth', 'nonexistent'], targetCommandMap);
44
- expect(result).toBe(false);
45
- });
46
- it('should return false for an empty command array', () => {
47
- const result = isTargetedCommand([], targetCommandMap);
48
- expect(result).toBe(false);
49
- });
50
- });
51
- });
@@ -1,8 +0,0 @@
1
- type TargetCommandMap = {
2
- [key: string]: {
3
- target?: boolean;
4
- subCommands?: TargetCommandMap;
5
- };
6
- };
7
- export declare function isTargetedCommand(commandParts: (string | number)[], targetCommandMap: TargetCommandMap): boolean;
8
- export {};
@@ -1,14 +0,0 @@
1
- export function isTargetedCommand(commandParts, targetCommandMap) {
2
- const currentCommand = commandParts[0];
3
- if (!targetCommandMap[currentCommand]) {
4
- return false;
5
- }
6
- if (targetCommandMap[currentCommand].target) {
7
- return true;
8
- }
9
- const subCommands = targetCommandMap[currentCommand].subCommands || {};
10
- if (commandParts.length > 1) {
11
- return isTargetedCommand(commandParts.slice(1), subCommands);
12
- }
13
- return false;
14
- }