Skip to content

Commit 203e1ec

Browse files
Sync from internal - version 8.1.0 (#1588)
1 parent 0bd2ad1 commit 203e1ec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+4079
-833
lines changed

.github/ISSUE_TEMPLATE.md

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Bug Report
2+
description: Report a problem with the HubSpot CLI
3+
labels: ['bug']
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Thanks for taking the time to report a bug. Please fill out the information below so we can investigate.
9+
10+
- type: input
11+
id: cli-version
12+
attributes:
13+
label: CLI Version
14+
description: 'Which version of the HubSpot CLI are you using? (Run `hs --version` to find out)'
15+
placeholder: '6.2.0'
16+
validations:
17+
required: true
18+
19+
- type: input
20+
id: node-version
21+
attributes:
22+
label: Node.js Version
23+
description: 'Which version of Node.js are you running? (Run `node --version` to find out)'
24+
placeholder: '20.11.0'
25+
validations:
26+
required: true
27+
28+
- type: input
29+
id: os
30+
attributes:
31+
label: Operating System
32+
description: 'Which OS are you on?'
33+
placeholder: 'macOS 15.3, Windows 11, Ubuntu 24.04, etc.'
34+
validations:
35+
required: true
36+
37+
- type: textarea
38+
id: description
39+
attributes:
40+
label: Description
41+
description: A clear description of the bug.
42+
placeholder: 'Describe what went wrong.'
43+
validations:
44+
required: true
45+
46+
- type: textarea
47+
id: reproduce
48+
attributes:
49+
label: Steps to Reproduce
50+
description: How can we reproduce this issue?
51+
placeholder: |
52+
1. Run `hs ...`
53+
2. ...
54+
3. See error
55+
validations:
56+
required: true
57+
58+
- type: textarea
59+
id: expected
60+
attributes:
61+
label: Expected Behavior
62+
description: What did you expect to happen?
63+
validations:
64+
required: true
65+
66+
- type: textarea
67+
id: screenshots
68+
attributes:
69+
label: Screenshots
70+
description: If applicable, add screenshots to help explain the problem.
71+
72+
- type: textarea
73+
id: additional
74+
attributes:
75+
label: Additional Context
76+
description: Any other context, error messages, or relevant log output.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Feature Request
2+
description: Suggest an enhancement or new capability
3+
labels: ['enhancement']
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Thanks for suggesting a feature! Please describe your idea so we can evaluate it.
9+
10+
- type: textarea
11+
id: problem
12+
attributes:
13+
label: Problem or Motivation
14+
description: What problem does this feature solve, or what workflow does it improve?
15+
placeholder: "I'm always frustrated when..."
16+
validations:
17+
required: true
18+
19+
- type: textarea
20+
id: solution
21+
attributes:
22+
label: Proposed Solution
23+
description: How would you like this to work?
24+
validations:
25+
required: true
26+
27+
- type: textarea
28+
id: alternatives
29+
attributes:
30+
label: Alternatives Considered
31+
description: Have you considered any workarounds or alternative approaches?
32+
33+
- type: textarea
34+
id: additional
35+
attributes:
36+
label: Additional Context
37+
description: Any other context or screenshots.

bin/cli.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import mcpCommand from '../commands/mcp.js';
4343
import upgradeCommand from '../commands/upgrade.js';
4444
import { uiLogger } from '../lib/ui/logger.js';
4545
import { initializeSpinniesManager } from '../lib/middleware/spinniesMiddleware.js';
46+
import { addCommandSuggestions } from '../lib/commandSuggestion.js';
4647

4748
function getTerminalWidth(): number {
4849
const width = yargs().terminalWidth();
@@ -131,23 +132,27 @@ const argv = yargs(process.argv.slice(2))
131132
.command(completionCommand)
132133
.command(doctorCommand)
133134
.command(mcpCommand)
134-
.command(upgradeCommand)
135+
.command(upgradeCommand);
135136

137+
const argvWithSuggestions = addCommandSuggestions(argv)
136138
.help()
137139
.alias('h', 'help')
138140
.recommendCommands()
139141
.demandCommand(1, '')
140142
.wrap(getTerminalWidth())
141143
.strict().argv;
142144

143-
if ('help' in argv && argv.help !== undefined) {
145+
if ('help' in argvWithSuggestions && argvWithSuggestions.help !== undefined) {
144146
(async () => {
145-
await trackHelpUsage(getCommandName(argv));
147+
await trackHelpUsage(getCommandName(argvWithSuggestions));
146148
})();
147149
}
148150

149-
if ('convertFields' in argv && argv.convertFields !== undefined) {
151+
if (
152+
'convertFields' in argvWithSuggestions &&
153+
argvWithSuggestions.convertFields !== undefined
154+
) {
150155
(async () => {
151-
await trackConvertFieldsUsage(getCommandName(argv));
156+
await trackConvertFieldsUsage(getCommandName(argvWithSuggestions));
152157
})();
153158
}

commands/__tests__/getStarted.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
import { GET_STARTED_OPTIONS } from '../../lib/constants.js';
1818
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
1919
import open from 'open';
20+
import { renderInteractive } from '../../ui/render.js';
21+
import { getGetStartedFlow } from '../../ui/components/getStarted/GetStartedFlow.js';
2022

2123
vi.mock('../../lib/prompts/promptUtils');
2224
vi.mock('../../lib/prompts/projectNameAndDestPrompt');
@@ -25,6 +27,8 @@ vi.mock('../../lib/errorHandlers');
2527
vi.mock('@hubspot/local-dev-lib/github');
2628
vi.mock('../../lib/dependencyManagement');
2729
vi.mock('@hubspot/local-dev-lib/config');
30+
vi.mock('../../ui/render');
31+
vi.mock('../../ui/components/getStarted/GetStartedFlow');
2832

2933
vi.mock('open');
3034
vi.mock('fs-extra', () => ({
@@ -150,6 +154,21 @@ describe('commands/get-started', () => {
150154
{ url: true }
151155
);
152156
});
157+
158+
it('should use Ink flow when v2 flag is enabled', async () => {
159+
(
160+
getGetStartedFlow as MockedFunction<typeof getGetStartedFlow>
161+
).mockImplementation(() => null);
162+
(
163+
renderInteractive as MockedFunction<typeof renderInteractive>
164+
).mockResolvedValue(undefined);
165+
166+
await getStartedCommand.handler({ ...mockArgs, v2: true });
167+
168+
expect(renderInteractive).toHaveBeenCalled();
169+
expect(promptUser).not.toHaveBeenCalled();
170+
expect(process.exit).toHaveBeenCalledWith(EXIT_CODES.SUCCESS);
171+
});
153172
});
154173

155174
describe('App flow', () => {

commands/__tests__/project.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import validate from '../project/validate.js';
1717
import profileCommands from '../project/profile.js';
1818
import list from '../project/list.js';
1919
import projectCommand from '../project.js';
20+
import * as projectConfigLib from '../../lib/projects/config.js';
21+
import * as platformVersionLib from '../../lib/projects/platformVersion.js';
22+
import { uiLogger } from '../../lib/ui/logger.js';
2023

2124
vi.mock('../project/deploy');
2225
vi.mock('../project/create');
@@ -41,6 +44,8 @@ vi.mock('../project/installDeps');
4144
vi.mock('../project/lint');
4245
vi.mock('../project/profile');
4346
vi.mock('../../lib/commonOpts');
47+
vi.mock('../../lib/projects/config.js');
48+
vi.mock('../../lib/projects/platformVersion.js');
4449

4550
const commandSpy = vi
4651
.spyOn(yargs as Argv, 'command')
@@ -49,7 +54,21 @@ const demandCommandSpy = vi
4954
.spyOn(yargs as Argv, 'demandCommand')
5055
.mockReturnValue(yargs as Argv);
5156

57+
const getProjectConfigSpy = vi.spyOn(projectConfigLib, 'getProjectConfig');
58+
const isUnsupportedPlatformVersionSpy = vi.spyOn(
59+
platformVersionLib,
60+
'isUnsupportedPlatformVersion'
61+
);
62+
const processExitSpy = vi.spyOn(process, 'exit');
63+
const uiLoggerErrorSpy = vi.spyOn(uiLogger, 'error');
64+
5265
describe('commands/project', () => {
66+
beforeEach(() => {
67+
vi.clearAllMocks();
68+
// @ts-expect-error Mock implementation
69+
processExitSpy.mockImplementation(() => {});
70+
});
71+
5372
describe('command', () => {
5473
it('should have the correct command structure', () => {
5574
expect(projectCommand.command).toEqual(['project', 'projects']);
@@ -101,4 +120,23 @@ describe('commands/project', () => {
101120
expect(commandSpy).toHaveBeenCalledWith(module);
102121
});
103122
});
123+
124+
describe('middleware - validatePlatformVersion', () => {
125+
it('should have platform version validation functions available', () => {
126+
// Verify the necessary functions are available for middleware
127+
expect(getProjectConfigSpy).toBeDefined();
128+
expect(isUnsupportedPlatformVersionSpy).toBeDefined();
129+
expect(uiLoggerErrorSpy).toBeDefined();
130+
expect(processExitSpy).toBeDefined();
131+
});
132+
133+
it('should register middleware when building', async () => {
134+
// Verify middleware is registered during builder execution
135+
await projectCommand.builder(yargs as Argv);
136+
137+
// The middleware should be registered (we can't easily test async middleware execution)
138+
// but we verify the builder completes successfully
139+
expect(projectCommand.builder).toBeDefined();
140+
});
141+
});
104142
});

0 commit comments

Comments
 (0)