@hubspot/cli 8.5.0-beta.1 → 8.6.0-beta.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/commands/account/clean.js +2 -0
- package/commands/account/createOverride.js +3 -0
- package/commands/account/info.js +34 -16
- package/commands/account/link.d.ts +4 -0
- package/commands/account/link.js +89 -0
- package/commands/account/list.js +29 -71
- package/commands/account/remove.js +2 -0
- package/commands/account/removeOverride.js +3 -0
- package/commands/account/unlink.d.ts +4 -0
- package/commands/account/unlink.js +70 -0
- package/commands/account/use.js +71 -1
- package/commands/account.js +4 -0
- package/commands/project/appInstallStatus.d.ts +4 -0
- package/commands/project/appInstallStatus.js +132 -0
- package/commands/project/create.js +8 -0
- package/commands/project/dev/deprecatedFlow.js +20 -2
- package/commands/project/dev/index.js +6 -0
- package/commands/project/dev/unifiedFlow.js +20 -3
- package/commands/project/lint.js +20 -2
- package/commands/project.js +2 -0
- package/lang/en.d.ts +102 -0
- package/lang/en.js +116 -8
- package/lib/app/migrate.js +2 -1
- package/lib/constants.d.ts +1 -0
- package/lib/constants.js +3 -0
- package/lib/doctor/Doctor.js +5 -5
- package/lib/link/accountTableUtils.d.ts +10 -0
- package/lib/link/accountTableUtils.js +39 -0
- package/lib/link/index.d.ts +18 -0
- package/lib/link/index.js +185 -0
- package/lib/link/linkUtils.d.ts +5 -0
- package/lib/link/linkUtils.js +49 -0
- package/lib/link/prompts.d.ts +7 -0
- package/lib/link/prompts.js +126 -0
- package/lib/link/renderLinkedAccountsTable.d.ts +2 -0
- package/lib/link/renderLinkedAccountsTable.js +14 -0
- package/lib/link/warnIfLinkedDirectory.d.ts +1 -0
- package/lib/link/warnIfLinkedDirectory.js +9 -0
- package/lib/projects/localDev/DevServerManager_DEPRECATED.d.ts +2 -1
- package/lib/projects/localDev/DevServerManager_DEPRECATED.js +2 -2
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.d.ts +2 -0
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +3 -0
- package/lib/projects/uieLinting.d.ts +17 -3
- package/lib/projects/uieLinting.js +93 -28
- package/lib/prompts/promptUtils.js +1 -0
- package/lib/ui/accountTable.d.ts +8 -0
- package/lib/ui/accountTable.js +67 -0
- package/mcp-server/server.js +39 -1
- package/mcp-server/tools/index.js +2 -0
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +1 -1
- package/mcp-server/tools/project/CreateTestAccountTool.js +1 -1
- package/mcp-server/tools/project/DeployProjectTool.js +1 -1
- package/mcp-server/tools/project/FindProjectsTool.d.ts +15 -0
- package/mcp-server/tools/project/FindProjectsTool.js +60 -0
- package/mcp-server/tools/project/GetBuildLogsTool.js +1 -1
- package/mcp-server/tools/project/GetBuildStatusTool.js +1 -1
- package/mcp-server/tools/project/UploadProjectTools.js +1 -1
- package/mcp-server/tools/project/ValidateProjectTool.js +1 -1
- package/package.json +2 -2
- package/types/Link.d.ts +32 -0
- package/types/Link.js +5 -0
- package/types/PackageJson.d.ts +1 -0
- package/types/Prompts.d.ts +1 -0
- package/types/Yargs.d.ts +1 -0
|
@@ -14,6 +14,7 @@ import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
|
14
14
|
import { commands } from '../../lang/en.js';
|
|
15
15
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
16
16
|
import { renderList } from '../../ui/render.js';
|
|
17
|
+
import { warnIfLinkedDirectory } from '../../lib/link/warnIfLinkedDirectory.js';
|
|
17
18
|
const command = 'clean';
|
|
18
19
|
const describe = commands.account.subcommands.clean.describe;
|
|
19
20
|
async function handler(args) {
|
|
@@ -24,6 +25,7 @@ async function handler(args) {
|
|
|
24
25
|
uiLogger.log(commands.account.subcommands.clean.noResults);
|
|
25
26
|
return exit(EXIT_CODES.SUCCESS);
|
|
26
27
|
}
|
|
28
|
+
warnIfLinkedDirectory(args._);
|
|
27
29
|
const accountsToRemove = [];
|
|
28
30
|
SpinniesManager.init({
|
|
29
31
|
succeedColor: 'white',
|
|
@@ -12,11 +12,14 @@ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHand
|
|
|
12
12
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
13
13
|
import { commands } from '../../lang/en.js';
|
|
14
14
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
15
|
+
import { warnIfLinkedDirectory } from '../../lib/link/warnIfLinkedDirectory.js';
|
|
15
16
|
const command = 'create-override [account]';
|
|
16
17
|
const describe = commands.account.subcommands.createOverride.describe(DEFAULT_ACCOUNT_OVERRIDE_FILE_NAME);
|
|
17
18
|
async function handler(args) {
|
|
18
19
|
const { exit } = args;
|
|
19
20
|
let overrideDefaultAccount = args.account;
|
|
21
|
+
// TODO: Block this command when linked directory exists (next breaking change)
|
|
22
|
+
warnIfLinkedDirectory(args._);
|
|
20
23
|
const globalConfigExists = globalConfigFileExists();
|
|
21
24
|
if (!globalConfigExists) {
|
|
22
25
|
uiLogger.error(commands.account.subcommands.createOverride.errors.globalConfigNotFound);
|
package/commands/account/info.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { getConfigAccountById, getConfigDefaultAccount, getConfigFilePath, } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { getDefaultAccountOverrideFilePath } from '@hubspot/local-dev-lib/config/defaultAccountOverride';
|
|
3
|
+
import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/local-dev-lib/config/hsSettings';
|
|
4
|
+
import { isDirectoryLinked } from '../../lib/link/linkUtils.js';
|
|
3
5
|
import { getAccessToken } from '@hubspot/local-dev-lib/personalAccessKey';
|
|
6
|
+
import { uiAccountDescription } from '../../lib/ui/index.js';
|
|
4
7
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
5
8
|
import { indent } from '../../lib/ui/index.js';
|
|
6
9
|
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
@@ -9,31 +12,46 @@ import { uiLogger } from '../../lib/ui/logger.js';
|
|
|
9
12
|
import { renderList } from '../../ui/render.js';
|
|
10
13
|
const describe = commands.account.subcommands.info.describe;
|
|
11
14
|
const command = 'info [account]';
|
|
15
|
+
function logLinkedAccountInfo(hsSettingsPath, localDefaultAccount) {
|
|
16
|
+
uiLogger.log(commands.account.subcommands.info.linkedDefaultTitle);
|
|
17
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.info.settingsPath(hsSettingsPath)}`);
|
|
18
|
+
if (localDefaultAccount) {
|
|
19
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.info.linkedDefault(uiAccountDescription(localDefaultAccount))}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function logGlobalAccountInfo() {
|
|
23
|
+
const configPath = getConfigFilePath();
|
|
24
|
+
if (configPath) {
|
|
25
|
+
uiLogger.log(commands.account.subcommands.info.defaultAccountTitle);
|
|
26
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.info.configPath(configPath)}`);
|
|
27
|
+
const defaultAccount = getConfigDefaultAccount();
|
|
28
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.info.defaultAccount(defaultAccount.name)}`);
|
|
29
|
+
}
|
|
30
|
+
const overrideFilePath = getDefaultAccountOverrideFilePath();
|
|
31
|
+
if (overrideFilePath) {
|
|
32
|
+
uiLogger.log('');
|
|
33
|
+
uiLogger.log(commands.account.subcommands.info.overrideFilePathTitle);
|
|
34
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.info.overrideFilePath(overrideFilePath)}`);
|
|
35
|
+
const defaultAccount = getConfigDefaultAccount();
|
|
36
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.info.overrideAccount(defaultAccount.name)}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
12
39
|
async function handler(args) {
|
|
13
40
|
const { derivedAccountId } = args;
|
|
14
41
|
const config = getConfigAccountById(derivedAccountId);
|
|
15
|
-
// check if the provided account is using a personal access key, if not, show an error
|
|
16
42
|
if (config && config.authType === 'personalaccesskey') {
|
|
17
43
|
const { name, personalAccessKey, env } = config;
|
|
18
44
|
let scopeGroups = [];
|
|
19
45
|
const response = await getAccessToken(personalAccessKey, env, derivedAccountId);
|
|
20
46
|
scopeGroups = response.scopeGroups.map(s => [s]);
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const defaultAccount = getConfigDefaultAccount();
|
|
27
|
-
uiLogger.log(`${indent(1)}${commands.account.subcommands.info.defaultAccount(defaultAccount.name)}`);
|
|
47
|
+
const hsSettings = getHsSettingsFileIfExists();
|
|
48
|
+
const hsSettingsPath = getHsSettingsFilePath();
|
|
49
|
+
const isLinked = isDirectoryLinked(hsSettings) && hsSettingsPath !== null;
|
|
50
|
+
if (isLinked) {
|
|
51
|
+
logLinkedAccountInfo(hsSettingsPath, hsSettings.localDefaultAccount);
|
|
28
52
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (overrideFilePath) {
|
|
32
|
-
uiLogger.log('');
|
|
33
|
-
uiLogger.log(commands.account.subcommands.info.overrideFilePathTitle);
|
|
34
|
-
uiLogger.log(`${indent(1)}${commands.account.subcommands.info.overrideFilePath(overrideFilePath)}`);
|
|
35
|
-
const defaultAccount = getConfigDefaultAccount();
|
|
36
|
-
uiLogger.log(`${indent(1)}${commands.account.subcommands.info.overrideAccount(defaultAccount.name)}`);
|
|
53
|
+
else {
|
|
54
|
+
logGlobalAccountInfo();
|
|
37
55
|
}
|
|
38
56
|
uiLogger.log('');
|
|
39
57
|
uiLogger.log(commands.account.subcommands.info.name(name));
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
2
|
+
import { uiLogger } from '../../lib/ui/logger.js';
|
|
3
|
+
import { getAllConfigAccounts } from '@hubspot/local-dev-lib/config';
|
|
4
|
+
import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
5
|
+
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
6
|
+
import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/local-dev-lib/config/hsSettings';
|
|
7
|
+
import { getDefaultAccountOverrideAccountId } from '@hubspot/local-dev-lib/config/defaultAccountOverride';
|
|
8
|
+
import { checkAndAddHsFolderToGitignore } from '@hubspot/local-dev-lib/gitignore';
|
|
9
|
+
import { DEFAULT_HS_SETTINGS_PATH, EMPTY_HS_SETTINGS_FILE, } from '@hubspot/local-dev-lib/constants/config';
|
|
10
|
+
import { ACTION_RESULT_STATUS } from '../../types/Link.js';
|
|
11
|
+
import { handleLinkFlow } from '../../lib/link/index.js';
|
|
12
|
+
import { hasDeprecatedConfigConflict, writeLinkedSettings, } from '../../lib/link/linkUtils.js';
|
|
13
|
+
import { renderLinkedAccountsTable } from '../../lib/link/renderLinkedAccountsTable.js';
|
|
14
|
+
import { commands } from '../../lang/en.js';
|
|
15
|
+
import { debugError } from '../../lib/errorHandlers/index.js';
|
|
16
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
17
|
+
const command = 'link';
|
|
18
|
+
// Hide the command until we're done testing and ready to make linking GA
|
|
19
|
+
// const describe = commands.account.subcommands.link.describe;
|
|
20
|
+
const describe = undefined;
|
|
21
|
+
async function handler(args) {
|
|
22
|
+
const { exit } = args;
|
|
23
|
+
if (hasDeprecatedConfigConflict(args._)) {
|
|
24
|
+
return exit(EXIT_CODES.ERROR);
|
|
25
|
+
}
|
|
26
|
+
const existingSettings = getHsSettingsFileIfExists();
|
|
27
|
+
const isNewFile = existingSettings === null;
|
|
28
|
+
if (isNewFile) {
|
|
29
|
+
uiLogger.log(commands.account.subcommands.link.linkingDirectory(getCwd()));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
uiLogger.log(commands.account.subcommands.link.managingLinkedAccounts(getCwd()));
|
|
33
|
+
}
|
|
34
|
+
uiLogger.log('');
|
|
35
|
+
const settingsFilePath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
|
|
36
|
+
uiLogger.log(commands.account.subcommands.link.settingsInfo(settingsFilePath));
|
|
37
|
+
uiLogger.log('');
|
|
38
|
+
const settings = isNewFile ? EMPTY_HS_SETTINGS_FILE : existingSettings;
|
|
39
|
+
const accounts = getAllConfigAccounts();
|
|
40
|
+
const accountOverrideId = getDefaultAccountOverrideAccountId(accounts);
|
|
41
|
+
if (settings.accounts.length !== 0) {
|
|
42
|
+
await renderLinkedAccountsTable(settings);
|
|
43
|
+
uiLogger.log('');
|
|
44
|
+
}
|
|
45
|
+
const result = await handleLinkFlow({
|
|
46
|
+
settings,
|
|
47
|
+
accountOverrideId,
|
|
48
|
+
args,
|
|
49
|
+
});
|
|
50
|
+
if (result.status === ACTION_RESULT_STATUS.ERROR) {
|
|
51
|
+
uiLogger.error(result.reason);
|
|
52
|
+
return exit(EXIT_CODES.ERROR);
|
|
53
|
+
}
|
|
54
|
+
if (result.status === ACTION_RESULT_STATUS.NOOP) {
|
|
55
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
56
|
+
}
|
|
57
|
+
const settingsPath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
|
|
58
|
+
if (!writeLinkedSettings(result.settings, settingsPath)) {
|
|
59
|
+
return exit(EXIT_CODES.ERROR);
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
checkAndAddHsFolderToGitignore(settingsPath);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
debugError(e);
|
|
66
|
+
}
|
|
67
|
+
if (isNewFile) {
|
|
68
|
+
uiLogger.success(commands.account.subcommands.link.success.created(settingsPath));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
uiLogger.success(commands.account.subcommands.link.shared.savedToSettings(settingsPath));
|
|
72
|
+
}
|
|
73
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
74
|
+
}
|
|
75
|
+
function linkBuilder(yargs) {
|
|
76
|
+
yargs.example([['$0 link']]);
|
|
77
|
+
return yargs;
|
|
78
|
+
}
|
|
79
|
+
const builder = makeYargsBuilder(linkBuilder, command, commands.account.subcommands.link.verboseDescribe, {
|
|
80
|
+
useGlobalOptions: true,
|
|
81
|
+
useConfigOptions: true,
|
|
82
|
+
});
|
|
83
|
+
const linkCommand = {
|
|
84
|
+
command,
|
|
85
|
+
describe,
|
|
86
|
+
handler: makeYargsHandlerWithUsageTracking('account-link', handler),
|
|
87
|
+
builder,
|
|
88
|
+
};
|
|
89
|
+
export default linkCommand;
|
package/commands/account/list.js
CHANGED
|
@@ -1,92 +1,50 @@
|
|
|
1
|
-
import { getConfigFilePath,
|
|
1
|
+
import { getConfigFilePath, getConfigDefaultAccountIfExists, } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { getDefaultAccountOverrideFilePath } from '@hubspot/local-dev-lib/config/defaultAccountOverride';
|
|
3
|
+
import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/local-dev-lib/config/hsSettings';
|
|
4
|
+
import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
3
5
|
import { indent } from '../../lib/ui/index.js';
|
|
4
|
-
import { isSandbox, isDeveloperTestAccount } from '../../lib/accountTypes.js';
|
|
5
|
-
import { HUBSPOT_ACCOUNT_TYPES, HUBSPOT_ACCOUNT_TYPE_STRINGS, } from '@hubspot/local-dev-lib/constants/config';
|
|
6
6
|
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
7
7
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
8
8
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
9
9
|
import { commands } from '../../lang/en.js';
|
|
10
|
-
import {
|
|
10
|
+
import { renderAccountTable } from '../../lib/ui/accountTable.js';
|
|
11
|
+
import { renderLinkedAccountsTable } from '../../lib/link/renderLinkedAccountsTable.js';
|
|
12
|
+
import { isDirectoryLinked } from '../../lib/link/linkUtils.js';
|
|
11
13
|
const command = ['list', 'ls'];
|
|
12
14
|
const describe = commands.account.subcommands.list.describe;
|
|
13
|
-
function sortAndMapAccounts(accounts) {
|
|
14
|
-
const mappedAccountData = {};
|
|
15
|
-
// Standard and app developer accounts
|
|
16
|
-
accounts
|
|
17
|
-
.filter(p => p.accountType &&
|
|
18
|
-
(p.accountType === HUBSPOT_ACCOUNT_TYPES.STANDARD ||
|
|
19
|
-
p.accountType === HUBSPOT_ACCOUNT_TYPES.APP_DEVELOPER))
|
|
20
|
-
.forEach(account => {
|
|
21
|
-
mappedAccountData[account.accountId] = [account];
|
|
22
|
-
});
|
|
23
|
-
// Non-standard accounts (sandbox, developer test account)
|
|
24
|
-
accounts
|
|
25
|
-
.filter(p => p.accountType && (isSandbox(p) || isDeveloperTestAccount(p)))
|
|
26
|
-
.forEach(p => {
|
|
27
|
-
if (p.parentAccountId) {
|
|
28
|
-
mappedAccountData[p.parentAccountId] = [
|
|
29
|
-
...(mappedAccountData[p.parentAccountId] || []),
|
|
30
|
-
p,
|
|
31
|
-
];
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
mappedAccountData[p.accountId] = [p];
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
return mappedAccountData;
|
|
38
|
-
}
|
|
39
|
-
function getAccountData(mappedAccountData) {
|
|
40
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
|
-
const accountData = [];
|
|
42
|
-
Object.entries(mappedAccountData).forEach(([key, set]) => {
|
|
43
|
-
const hasParentAccount = set.filter(p => p.accountId === parseInt(key, 10))[0];
|
|
44
|
-
set.forEach(account => {
|
|
45
|
-
let name = `${account.name} [${HUBSPOT_ACCOUNT_TYPE_STRINGS[account.accountType]}]`;
|
|
46
|
-
if (isSandbox(account)) {
|
|
47
|
-
if (hasParentAccount && set.length > 1) {
|
|
48
|
-
name = `↳ ${name}`;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
else if (isDeveloperTestAccount(account)) {
|
|
52
|
-
if (hasParentAccount && set.length > 1) {
|
|
53
|
-
name = `↳ ${name}`;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
accountData.push([name, account.accountId, account.authType]);
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
return accountData;
|
|
60
|
-
}
|
|
61
15
|
async function handler() {
|
|
62
16
|
const configPath = getConfigFilePath();
|
|
63
|
-
const accountsList = getAllConfigAccounts();
|
|
64
|
-
const mappedAccountData = sortAndMapAccounts(accountsList);
|
|
65
|
-
const accountData = getAccountData(mappedAccountData);
|
|
66
|
-
const tableHeader = [
|
|
67
|
-
commands.account.subcommands.list.labels.name,
|
|
68
|
-
commands.account.subcommands.list.labels.accountId,
|
|
69
|
-
commands.account.subcommands.list.labels.authType,
|
|
70
|
-
];
|
|
71
17
|
const defaultAccount = getConfigDefaultAccountIfExists();
|
|
72
18
|
const accountId = defaultAccount?.accountId;
|
|
73
19
|
const overrideFilePath = getDefaultAccountOverrideFilePath();
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
uiLogger.log(
|
|
20
|
+
const hsSettings = getHsSettingsFileIfExists();
|
|
21
|
+
const hsSettingsPath = getHsSettingsFilePath();
|
|
22
|
+
const isLinked = isDirectoryLinked(hsSettings);
|
|
23
|
+
if (isLinked && hsSettingsPath) {
|
|
24
|
+
uiLogger.log(commands.account.subcommands.list.linkedDefaultTitle);
|
|
25
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.list.directory(getCwd())}`);
|
|
26
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.list.configPath(hsSettingsPath)}`);
|
|
27
|
+
if (hsSettings.localDefaultAccount) {
|
|
28
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.list.currentResolvedDefaultAccount(hsSettings.localDefaultAccount)}`);
|
|
29
|
+
}
|
|
30
|
+
uiLogger.log('');
|
|
31
|
+
uiLogger.log(commands.account.subcommands.list.linkedAccounts);
|
|
32
|
+
await renderLinkedAccountsTable(hsSettings);
|
|
79
33
|
uiLogger.log('');
|
|
80
34
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
uiLogger.log(commands.account.subcommands.list.
|
|
84
|
-
uiLogger.log(`${indent(1)}${commands.account.subcommands.list.overrideFilePath(overrideFilePath)}`);
|
|
35
|
+
if (!isLinked && configPath && accountId) {
|
|
36
|
+
uiLogger.log(commands.account.subcommands.list.defaultAccountTitle);
|
|
37
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.list.configPath(configPath)}`);
|
|
85
38
|
uiLogger.log(`${indent(1)}${commands.account.subcommands.list.currentResolvedDefaultAccount(accountId)}`);
|
|
86
39
|
uiLogger.log('');
|
|
40
|
+
if (overrideFilePath) {
|
|
41
|
+
uiLogger.log(commands.account.subcommands.list.overrideFilePathTitle);
|
|
42
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.list.overrideFilePath(overrideFilePath)}`);
|
|
43
|
+
uiLogger.log(`${indent(1)}${commands.account.subcommands.list.currentResolvedDefaultAccount(accountId)}`);
|
|
44
|
+
uiLogger.log('');
|
|
45
|
+
}
|
|
87
46
|
}
|
|
88
|
-
|
|
89
|
-
renderTable(tableHeader, accountData, true);
|
|
47
|
+
renderAccountTable(isLinked);
|
|
90
48
|
}
|
|
91
49
|
function accountListBuilder(yargs) {
|
|
92
50
|
yargs.example([['$0 accounts list']]);
|
|
@@ -8,9 +8,11 @@ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHand
|
|
|
8
8
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
9
9
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
10
10
|
import { commands } from '../../lang/en.js';
|
|
11
|
+
import { warnIfLinkedDirectory } from '../../lib/link/warnIfLinkedDirectory.js';
|
|
11
12
|
const command = 'remove [account]';
|
|
12
13
|
const describe = commands.account.subcommands.remove.describe;
|
|
13
14
|
async function handler(args) {
|
|
15
|
+
warnIfLinkedDirectory(args._);
|
|
14
16
|
const { account: accountFlag } = args;
|
|
15
17
|
let accountToRemoveConfig = accountFlag
|
|
16
18
|
? getConfigAccountIfExists(accountFlag)
|
|
@@ -9,10 +9,13 @@ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHand
|
|
|
9
9
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
10
10
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
11
11
|
import { commands } from '../../lang/en.js';
|
|
12
|
+
import { warnIfLinkedDirectory } from '../../lib/link/warnIfLinkedDirectory.js';
|
|
12
13
|
const command = 'remove-override';
|
|
13
14
|
const describe = commands.account.subcommands.removeOverride.describe(DEFAULT_ACCOUNT_OVERRIDE_FILE_NAME);
|
|
14
15
|
async function handler(args) {
|
|
15
16
|
const { force, exit } = args;
|
|
17
|
+
// TODO: Block this command when linked directory exists (next breaking change)
|
|
18
|
+
warnIfLinkedDirectory(args._);
|
|
16
19
|
const globalConfigExists = globalConfigFileExists();
|
|
17
20
|
if (!globalConfigExists) {
|
|
18
21
|
uiLogger.error(commands.account.subcommands.removeOverride.errors.globalConfigNotFound);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
2
|
+
import { uiLogger } from '../../lib/ui/logger.js';
|
|
3
|
+
import { getAllConfigAccounts } from '@hubspot/local-dev-lib/config';
|
|
4
|
+
import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
5
|
+
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
6
|
+
import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/local-dev-lib/config/hsSettings';
|
|
7
|
+
import { ACTION_RESULT_STATUS } from '../../types/Link.js';
|
|
8
|
+
import { ActionHandlers } from '../../lib/link/index.js';
|
|
9
|
+
import { hasDeprecatedConfigConflict, isDirectoryLinked, writeLinkedSettings, } from '../../lib/link/linkUtils.js';
|
|
10
|
+
import { commands } from '../../lang/en.js';
|
|
11
|
+
import { DEFAULT_HS_SETTINGS_PATH } from '@hubspot/local-dev-lib/constants/config';
|
|
12
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
13
|
+
const command = 'unlink';
|
|
14
|
+
// Hide the command until we're done testing and ready to make linking GA
|
|
15
|
+
// const describe = commands.account.subcommands.link.describe;
|
|
16
|
+
const describe = undefined;
|
|
17
|
+
async function handler(args) {
|
|
18
|
+
const { exit } = args;
|
|
19
|
+
if (hasDeprecatedConfigConflict(args._)) {
|
|
20
|
+
return exit(EXIT_CODES.ERROR);
|
|
21
|
+
}
|
|
22
|
+
const existingSettings = getHsSettingsFileIfExists();
|
|
23
|
+
if (!isDirectoryLinked(existingSettings)) {
|
|
24
|
+
const globalAccounts = getAllConfigAccounts();
|
|
25
|
+
uiLogger.log(commands.account.subcommands.link.shared.noLinkedAccounts);
|
|
26
|
+
uiLogger.log(commands.account.subcommands.link.shared.globalAccountsAvailable(globalAccounts.length));
|
|
27
|
+
uiLogger.log('');
|
|
28
|
+
uiLogger.log(commands.account.subcommands.link.shared.configurePrompt);
|
|
29
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
30
|
+
}
|
|
31
|
+
uiLogger.log(commands.account.subcommands.link.managingLinkedAccounts(getCwd()));
|
|
32
|
+
uiLogger.log('');
|
|
33
|
+
const result = await ActionHandlers.unlink({
|
|
34
|
+
state: existingSettings,
|
|
35
|
+
context: {
|
|
36
|
+
globalAccountsList: getAllConfigAccounts(),
|
|
37
|
+
globalDefaultAccount: undefined,
|
|
38
|
+
accountOverrideId: null,
|
|
39
|
+
},
|
|
40
|
+
args,
|
|
41
|
+
});
|
|
42
|
+
if (result.status === ACTION_RESULT_STATUS.ERROR) {
|
|
43
|
+
uiLogger.error(result.reason);
|
|
44
|
+
return exit(EXIT_CODES.ERROR);
|
|
45
|
+
}
|
|
46
|
+
if (result.status === ACTION_RESULT_STATUS.NOOP) {
|
|
47
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
48
|
+
}
|
|
49
|
+
const settingsPath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
|
|
50
|
+
if (!writeLinkedSettings(result.settings, settingsPath)) {
|
|
51
|
+
return exit(EXIT_CODES.ERROR);
|
|
52
|
+
}
|
|
53
|
+
uiLogger.success(commands.account.subcommands.link.shared.savedToSettings(settingsPath));
|
|
54
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
55
|
+
}
|
|
56
|
+
function unlinkBuilder(yargs) {
|
|
57
|
+
yargs.example([['$0 account unlink']]);
|
|
58
|
+
return yargs;
|
|
59
|
+
}
|
|
60
|
+
const builder = makeYargsBuilder(unlinkBuilder, command, commands.account.subcommands.unlink.verboseDescribe, {
|
|
61
|
+
useGlobalOptions: true,
|
|
62
|
+
useConfigOptions: true,
|
|
63
|
+
});
|
|
64
|
+
const unlinkCommand = {
|
|
65
|
+
command,
|
|
66
|
+
describe,
|
|
67
|
+
handler: makeYargsHandlerWithUsageTracking('account-unlink', handler),
|
|
68
|
+
builder,
|
|
69
|
+
};
|
|
70
|
+
export default unlinkCommand;
|
package/commands/account/use.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { getConfigFilePath, setConfigAccountAsDefault, getConfigAccountIfExists, getConfigAccountByName, getConfigAccountById, globalConfigFileExists, getAllConfigAccounts, } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { getDefaultAccountOverrideAccountId, getDefaultAccountOverrideFilePath, } from '@hubspot/local-dev-lib/config/defaultAccountOverride';
|
|
3
|
+
import { getHsSettingsFileIfExists, getHsSettingsFilePath, writeHsSettingsFile, } from '@hubspot/local-dev-lib/config/hsSettings';
|
|
4
|
+
import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
3
5
|
import { ENVIRONMENTS } from '@hubspot/local-dev-lib/constants/environments';
|
|
4
6
|
import { commands } from '../../lang/en.js';
|
|
5
7
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
@@ -8,9 +10,69 @@ import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHand
|
|
|
8
10
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
9
11
|
import { authenticateNewAccount } from '../../lib/accountAuth.js';
|
|
10
12
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
13
|
+
import { confirmPrompt } from '../../lib/prompts/promptUtils.js';
|
|
14
|
+
import { handleLinkedUseAction } from '../../lib/link/index.js';
|
|
15
|
+
import { isDirectoryLinked } from '../../lib/link/linkUtils.js';
|
|
16
|
+
import { ACTION_RESULT_STATUS } from '../../types/Link.js';
|
|
17
|
+
import { DEFAULT_HS_SETTINGS_PATH } from '@hubspot/local-dev-lib/constants/config';
|
|
11
18
|
const command = 'use [account]';
|
|
12
19
|
const describe = commands.account.subcommands.use.describe;
|
|
13
|
-
async function
|
|
20
|
+
async function handleLinkedUse(args, hsSettings) {
|
|
21
|
+
const { exit } = args;
|
|
22
|
+
uiLogger.log(commands.account.subcommands.use.linked.editingLinkedDefault(getCwd()));
|
|
23
|
+
uiLogger.log('');
|
|
24
|
+
if (!args.account && hsSettings.accounts.length === 1) {
|
|
25
|
+
uiLogger.log(commands.account.subcommands.use.linked.alreadyDefault(hsSettings.accounts[0]));
|
|
26
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
27
|
+
}
|
|
28
|
+
let targetAccountId;
|
|
29
|
+
if (args.account) {
|
|
30
|
+
const account = getConfigAccountIfExists(args.account);
|
|
31
|
+
if (!account) {
|
|
32
|
+
uiLogger.error(commands.account.subcommands.use.errors.accountNotFound(args.account, getConfigFilePath()));
|
|
33
|
+
return exit(EXIT_CODES.ERROR);
|
|
34
|
+
}
|
|
35
|
+
if (!hsSettings.accounts.includes(account.accountId)) {
|
|
36
|
+
if (!process.stdin.isTTY) {
|
|
37
|
+
uiLogger.log(commands.account.subcommands.use.linked.nonInteractiveNotLinked(account.name));
|
|
38
|
+
setConfigAccountAsDefault(String(args.account));
|
|
39
|
+
uiLogger.success(commands.account.subcommands.use.success.defaultAccountUpdated(account.name));
|
|
40
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
41
|
+
}
|
|
42
|
+
uiLogger.log(commands.account.subcommands.use.linked.accountNotLinked(account.name));
|
|
43
|
+
const shouldLink = await confirmPrompt(commands.account.subcommands.use.linked.promptToLink(account.name));
|
|
44
|
+
if (!shouldLink) {
|
|
45
|
+
uiLogger.log(commands.account.subcommands.use.linked.settingGlobalDefault);
|
|
46
|
+
setConfigAccountAsDefault(String(args.account));
|
|
47
|
+
uiLogger.success(commands.account.subcommands.use.success.defaultAccountUpdated(account.name));
|
|
48
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
targetAccountId = account.accountId;
|
|
52
|
+
}
|
|
53
|
+
const result = await handleLinkedUseAction({
|
|
54
|
+
state: hsSettings,
|
|
55
|
+
targetAccountId,
|
|
56
|
+
});
|
|
57
|
+
if (result.status === ACTION_RESULT_STATUS.ERROR) {
|
|
58
|
+
uiLogger.error(result.reason);
|
|
59
|
+
return exit(EXIT_CODES.ERROR);
|
|
60
|
+
}
|
|
61
|
+
if (result.status === ACTION_RESULT_STATUS.NOOP) {
|
|
62
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
63
|
+
}
|
|
64
|
+
const settingsPath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
|
|
65
|
+
try {
|
|
66
|
+
writeHsSettingsFile(result.settings);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
uiLogger.error(commands.account.subcommands.link.shared.writeSettingsFailed(settingsPath, err));
|
|
70
|
+
return exit(EXIT_CODES.ERROR);
|
|
71
|
+
}
|
|
72
|
+
uiLogger.success(commands.account.subcommands.link.shared.savedToSettings(settingsPath));
|
|
73
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
74
|
+
}
|
|
75
|
+
async function handleGlobalUse(args) {
|
|
14
76
|
const { exit } = args;
|
|
15
77
|
let newDefaultAccount = args.account;
|
|
16
78
|
const usingGlobalConfig = globalConfigFileExists();
|
|
@@ -52,6 +114,14 @@ async function handler(args) {
|
|
|
52
114
|
setConfigAccountAsDefault(String(newDefaultAccount));
|
|
53
115
|
return uiLogger.success(commands.account.subcommands.use.success.defaultAccountUpdated(account.name));
|
|
54
116
|
}
|
|
117
|
+
async function handler(args) {
|
|
118
|
+
const hsSettings = getHsSettingsFileIfExists();
|
|
119
|
+
const isLinked = isDirectoryLinked(hsSettings);
|
|
120
|
+
if (isLinked) {
|
|
121
|
+
return handleLinkedUse(args, hsSettings);
|
|
122
|
+
}
|
|
123
|
+
return handleGlobalUse(args);
|
|
124
|
+
}
|
|
55
125
|
function accountUseBuilder(yargs) {
|
|
56
126
|
yargs.positional('account', {
|
|
57
127
|
describe: commands.account.subcommands.use.options.account.describe,
|
package/commands/account.js
CHANGED
|
@@ -8,12 +8,16 @@ import remove from './account/remove.js';
|
|
|
8
8
|
import clean from './account/clean.js';
|
|
9
9
|
import createOverride from './account/createOverride.js';
|
|
10
10
|
import removeOverride from './account/removeOverride.js';
|
|
11
|
+
import link from './account/link.js';
|
|
12
|
+
import unlink from './account/unlink.js';
|
|
11
13
|
import { makeYargsBuilder } from '../lib/yargsUtils.js';
|
|
12
14
|
const command = ['account', 'accounts'];
|
|
13
15
|
const describe = commands.account.describe;
|
|
14
16
|
function accountBuilder(yargs) {
|
|
15
17
|
yargs
|
|
16
18
|
.command(auth)
|
|
19
|
+
.command(link)
|
|
20
|
+
.command(unlink)
|
|
17
21
|
.command(list)
|
|
18
22
|
.command(rename)
|
|
19
23
|
.command(use)
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AccountArgs, CommonArgs, ConfigArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
type ProjectInstallStatusArgs = CommonArgs & ConfigArgs & AccountArgs & JSONOutputArgs;
|
|
3
|
+
declare const projectInstallStatusCommand: YargsCommandModule<unknown, ProjectInstallStatusArgs>;
|
|
4
|
+
export default projectInstallStatusCommand;
|