Skip to content

Commit 8b6c017

Browse files
authored
Support projectAccount and testingAccount flags + clean up unified app account logic (#1542)
1 parent 05a2fd1 commit 8b6c017

5 files changed

Lines changed: 187 additions & 135 deletions

File tree

commands/project/dev/deprecatedFlow.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { ArgumentsCamelCase } from 'yargs';
22
import { logger } from '@hubspot/local-dev-lib/logger';
3-
import { getConfigAccounts, getEnv } from '@hubspot/local-dev-lib/config';
4-
import { CLIAccount } from '@hubspot/local-dev-lib/types/Accounts';
3+
import {
4+
getAccountConfig,
5+
getConfigAccounts,
6+
getEnv,
7+
} from '@hubspot/local-dev-lib/config';
58
import { getValidEnv } from '@hubspot/local-dev-lib/environment';
69

710
import {
@@ -32,12 +35,19 @@ import { isSandbox, isDeveloperTestAccount } from '../../../lib/accountTypes';
3235
import { ensureProjectExists } from '../../../lib/projects/ensureProjectExists';
3336
import { ProjectDevArgs } from '../../../types/Yargs';
3437

35-
export async function deprecatedProjectDevFlow(
36-
args: ArgumentsCamelCase<ProjectDevArgs>,
37-
accountConfig: CLIAccount,
38-
projectConfig: ProjectConfig,
39-
projectDir: string
40-
): Promise<void> {
38+
type DeprecatedProjectDevFlowArgs = {
39+
args: ArgumentsCamelCase<ProjectDevArgs>;
40+
accountId: number;
41+
projectConfig: ProjectConfig;
42+
projectDir: string;
43+
};
44+
45+
export async function deprecatedProjectDevFlow({
46+
args,
47+
accountId,
48+
projectConfig,
49+
projectDir,
50+
}: DeprecatedProjectDevFlowArgs): Promise<void> {
4151
const { providedAccountId, derivedAccountId } = args;
4252
const env = getValidEnv(getEnv(derivedAccountId));
4353

@@ -47,6 +57,17 @@ export async function deprecatedProjectDevFlow(
4757
const hasPrivateApps = !!componentTypes[ComponentTypes.PrivateApp];
4858
const hasPublicApps = !!componentTypes[ComponentTypes.PublicApp];
4959

60+
const accountConfig = getAccountConfig(accountId);
61+
if (!accountConfig) {
62+
logger.error(
63+
i18n('commands.project.subcommands.dev.errors.noAccount', {
64+
accountId: accountId,
65+
authCommand: uiCommandReference('hs auth'),
66+
})
67+
);
68+
process.exit(EXIT_CODES.ERROR);
69+
}
70+
5071
if (runnableComponents.length === 0) {
5172
logger.error(
5273
i18n(`commands.project.subcommands.dev.errors.noRunnableComponents`, {

commands/project/dev/index.ts

Lines changed: 80 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
11
import { ArgumentsCamelCase, Argv, CommandModule } from 'yargs';
22
import { trackCommandUsage } from '../../../lib/usageTracking';
3-
import { i18n } from '../../../lib/lang';
4-
import { logger } from '@hubspot/local-dev-lib/logger';
5-
import { getAccountConfig } from '@hubspot/local-dev-lib/config';
3+
import { getAccountId } from '@hubspot/local-dev-lib/config';
64
import { HsProfileFile } from '@hubspot/project-parsing-lib/src/lib/types';
75
import {
86
getProjectConfig,
97
validateProjectConfig,
108
} from '../../../lib/projects/config';
119
import { EXIT_CODES } from '../../../lib/enums/exitCodes';
12-
import {
13-
uiBetaTag,
14-
uiCommandReference,
15-
uiLink,
16-
uiLine,
17-
uiAccountDescription,
18-
} from '../../../lib/ui';
10+
import { uiBetaTag, uiLine } from '../../../lib/ui';
1911
import { ProjectDevArgs } from '../../../types/Yargs';
2012
import { deprecatedProjectDevFlow } from './deprecatedFlow';
2113
import { unifiedProjectDevFlow } from './unifiedFlow';
@@ -27,36 +19,64 @@ import {
2719
logProfileHeader,
2820
exitIfUsingProfiles,
2921
} from '../../../lib/projectProfiles';
22+
import { commands } from '../../../lang/en';
23+
import { uiLogger } from '../../../lib/ui/logger';
3024

3125
const command = 'dev';
32-
const describe = uiBetaTag(
33-
i18n(`commands.project.subcommands.dev.describe`),
34-
false
35-
);
26+
const describe = uiBetaTag(commands.project.dev.describe, false);
27+
28+
function validateAccountFlags(
29+
testingAccount: string | number | undefined,
30+
projectAccount: string | number | undefined,
31+
providedAccountId: string | number | undefined,
32+
useV3: boolean
33+
) {
34+
// Legacy projects do not support targetTestingAccount and targetProjectAccount
35+
if (testingAccount && projectAccount && !useV3) {
36+
uiLogger.error(commands.project.dev.errors.unsupportedAccountFlagLegacy);
37+
process.exit(EXIT_CODES.ERROR);
38+
}
39+
40+
if (providedAccountId && useV3) {
41+
uiLogger.error(commands.project.dev.errors.unsupportedAccountFlagV3);
42+
process.exit(EXIT_CODES.ERROR);
43+
}
44+
}
3645

3746
async function handler(
3847
args: ArgumentsCamelCase<ProjectDevArgs>
3948
): Promise<void> {
40-
const { derivedAccountId, providedAccountId } = args;
49+
const {
50+
derivedAccountId,
51+
providedAccountId,
52+
testingAccount,
53+
projectAccount,
54+
} = args;
4155

4256
const { projectConfig, projectDir } = await getProjectConfig();
4357
validateProjectConfig(projectConfig, projectDir);
4458

59+
const useV3 = useV3Api(projectConfig.platformVersion);
60+
4561
if (!projectDir) {
46-
logger.error(
47-
i18n(`commands.project.subcommands.dev.errors.noProjectConfig`, {
48-
accountId: derivedAccountId,
49-
authCommand: uiCommandReference('hs auth'),
50-
})
51-
);
62+
uiLogger.error(commands.project.dev.errors.noProjectConfig);
5263
process.exit(EXIT_CODES.ERROR);
5364
}
5465

55-
let targetAccountId = providedAccountId;
66+
validateAccountFlags(
67+
testingAccount,
68+
projectAccount,
69+
providedAccountId,
70+
useV3
71+
);
72+
73+
let targetProjectAccountId =
74+
(projectAccount && getAccountId(projectAccount)) ||
75+
(providedAccountId && derivedAccountId);
5676

5777
let profile: HsProfileFile | undefined;
5878

59-
if (!targetAccountId && useV3Api(projectConfig.platformVersion)) {
79+
if (!targetProjectAccountId && useV3Api(projectConfig.platformVersion)) {
6080
if (args.profile) {
6181
logProfileHeader(args.profile);
6282

@@ -67,7 +87,7 @@ async function handler(
6787
process.exit(EXIT_CODES.ERROR);
6888
}
6989

70-
targetAccountId = profile.accountId;
90+
targetProjectAccountId = profile.accountId;
7191

7292
logProfileFooter(profile);
7393
} else {
@@ -76,68 +96,66 @@ async function handler(
7696
}
7797
}
7898

79-
if (!targetAccountId) {
80-
// The user is not using profiles, so we can use the derived accountId
81-
targetAccountId = derivedAccountId;
99+
if (!targetProjectAccountId) {
100+
// The user is not using profile or account flags, so we can use the derived accountId
101+
targetProjectAccountId = derivedAccountId;
82102
}
83103

84-
trackCommandUsage('project-dev', {}, targetAccountId);
85-
86-
const accountConfig = getAccountConfig(targetAccountId);
87-
88-
uiBetaTag(i18n(`commands.project.subcommands.dev.logs.betaMessage`));
104+
trackCommandUsage('project-dev', {}, targetProjectAccountId);
89105

90-
logger.log(
91-
uiLink(
92-
i18n(`commands.project.subcommands.dev.logs.learnMoreLocalDevServer`),
93-
'https://developers.hubspot.com/docs/platform/project-cli-commands#start-a-local-development-server'
94-
)
95-
);
106+
uiBetaTag(commands.project.dev.logs.betaMessage);
96107

97-
if (!accountConfig) {
98-
logger.error(
99-
i18n(`commands.project.subcommands.dev.errors.noAccount`, {
100-
accountId: uiAccountDescription(targetAccountId),
101-
authCommand: uiCommandReference('hs auth'),
102-
})
103-
);
104-
process.exit(EXIT_CODES.ERROR);
105-
}
108+
uiLogger.log(commands.project.dev.logs.learnMoreLocalDevServer);
106109

107110
if (useV3Api(projectConfig.platformVersion)) {
108-
await unifiedProjectDevFlow(
111+
const targetTestingAccountId =
112+
(testingAccount && getAccountId(testingAccount)) || undefined;
113+
114+
await unifiedProjectDevFlow({
109115
args,
110-
accountConfig,
116+
targetProjectAccountId,
117+
providedTargetTestingAccountId: targetTestingAccountId,
111118
projectConfig,
112119
projectDir,
113-
profile
114-
);
120+
profileConfig: profile,
121+
});
115122
} else {
116-
await deprecatedProjectDevFlow(
123+
await deprecatedProjectDevFlow({
117124
args,
118-
accountConfig,
125+
accountId: targetProjectAccountId,
119126
projectConfig,
120-
projectDir
121-
);
127+
projectDir,
128+
});
122129
}
123130
}
124131

125132
function projectDevBuilder(yargs: Argv): Argv<ProjectDevArgs> {
126133
yargs.option('profile', {
127134
type: 'string',
128135
alias: 'p',
129-
description: i18n(`commands.project.subcommands.dev.options.profile`),
136+
description: commands.project.dev.options.profile,
137+
hidden: true,
138+
});
139+
140+
yargs.options('testingAccount', {
141+
type: 'string',
142+
description: commands.project.dev.options.testingAccount,
143+
hidden: true,
144+
implies: ['projectAccount'],
145+
});
146+
147+
yargs.options('projectAccount', {
148+
type: 'string',
149+
description: commands.project.dev.options.projectAccount,
130150
hidden: true,
151+
implies: ['testingAccount'],
131152
});
132153

133-
yargs.example([
134-
[
135-
'$0 project dev',
136-
i18n(`commands.project.subcommands.dev.examples.default`),
137-
],
138-
]);
154+
yargs.example([['$0 project dev', commands.project.dev.examples.default]]);
139155

140156
yargs.conflicts('profile', 'account');
157+
yargs.conflicts('profile', 'testingAccount');
158+
yargs.conflicts('profile', 'projectAccount');
141159

142160
return yargs as Argv<ProjectDevArgs>;
143161
}

0 commit comments

Comments
 (0)