@hubspot/cli 8.0.12-experimental.0 → 8.0.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.
- package/bin/cli.js +4 -3
- 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.js +3 -2
- 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.js +3 -2
- package/commands/account/use.js +71 -1
- 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 +18 -1
- package/commands/project/upload.js +27 -15
- package/lang/en.d.ts +28 -0
- package/lang/en.js +33 -4
- package/lib/constants.d.ts +2 -0
- package/lib/constants.js +4 -0
- package/lib/doctor/Doctor.js +5 -5
- package/lib/link/index.d.ts +4 -0
- package/lib/link/index.js +40 -9
- package/lib/link/linkUtils.d.ts +1 -0
- package/lib/link/linkUtils.js +26 -1
- 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/preview.js +11 -24
- package/lib/projects/uieLinting.d.ts +9 -0
- package/lib/projects/uieLinting.js +45 -1
- package/lib/ui/accountTable.d.ts +8 -0
- package/lib/ui/accountTable.js +67 -0
- package/lib/yargs/parseYargsOrExit.d.ts +4 -0
- package/lib/yargs/parseYargsOrExit.js +25 -0
- package/mcp-server/server.js +8 -4
- 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 +1 -1
- package/types/Link.d.ts +8 -3
- package/types/Link.js +5 -1
- package/types/PackageJson.d.ts +1 -0
- package/types/Yargs.d.ts +1 -0
package/bin/cli.js
CHANGED
|
@@ -36,6 +36,7 @@ import { uiLogger } from '../lib/ui/logger.js';
|
|
|
36
36
|
import { initializeSpinniesManager } from '../lib/middleware/spinniesMiddleware.js';
|
|
37
37
|
import { addCommandSuggestions } from '../lib/commandSuggestion.js';
|
|
38
38
|
import { pkg } from '../lib/jsonLoader.js';
|
|
39
|
+
import { parseYargsOrExit } from '../lib/yargs/parseYargsOrExit.js';
|
|
39
40
|
function getTerminalWidth() {
|
|
40
41
|
const width = yargs().terminalWidth();
|
|
41
42
|
if (width >= 100)
|
|
@@ -74,7 +75,6 @@ const argv = yargs(process.argv.slice(2))
|
|
|
74
75
|
initializeSpinniesManager,
|
|
75
76
|
])
|
|
76
77
|
.exitProcess(false)
|
|
77
|
-
.fail(handleFailure)
|
|
78
78
|
.option('noHyperlinks', {
|
|
79
79
|
default: false,
|
|
80
80
|
describe: 'prevent hyperlinks from displaying in the ui',
|
|
@@ -119,7 +119,7 @@ const argv = yargs(process.argv.slice(2))
|
|
|
119
119
|
.command(doctorCommand)
|
|
120
120
|
.command(mcpCommand)
|
|
121
121
|
.command(upgradeCommand);
|
|
122
|
-
const
|
|
122
|
+
const parser = addCommandSuggestions(argv)
|
|
123
123
|
.help()
|
|
124
124
|
.alias('h', 'help')
|
|
125
125
|
.version(pkg.version)
|
|
@@ -127,7 +127,8 @@ const argvWithSuggestions = addCommandSuggestions(argv)
|
|
|
127
127
|
.recommendCommands()
|
|
128
128
|
.demandCommand(1, '')
|
|
129
129
|
.wrap(getTerminalWidth())
|
|
130
|
-
.strict()
|
|
130
|
+
.strict();
|
|
131
|
+
const argvWithSuggestions = await parseYargsOrExit(parser, handleFailure);
|
|
131
132
|
if ('help' in argvWithSuggestions && argvWithSuggestions.help !== undefined) {
|
|
132
133
|
(async () => {
|
|
133
134
|
await trackHelpUsage(getCommandName(argvWithSuggestions));
|
|
@@ -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));
|
package/commands/account/link.js
CHANGED
|
@@ -7,6 +7,7 @@ import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/loca
|
|
|
7
7
|
import { getDefaultAccountOverrideAccountId } from '@hubspot/local-dev-lib/config/defaultAccountOverride';
|
|
8
8
|
import { checkAndAddHsFolderToGitignore } from '@hubspot/local-dev-lib/gitignore';
|
|
9
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';
|
|
10
11
|
import { handleLinkFlow } from '../../lib/link/index.js';
|
|
11
12
|
import { hasDeprecatedConfigConflict, writeLinkedSettings, } from '../../lib/link/linkUtils.js';
|
|
12
13
|
import { renderLinkedAccountsTable } from '../../lib/link/renderLinkedAccountsTable.js';
|
|
@@ -46,11 +47,11 @@ async function handler(args) {
|
|
|
46
47
|
accountOverrideId,
|
|
47
48
|
args,
|
|
48
49
|
});
|
|
49
|
-
if (result.status ===
|
|
50
|
+
if (result.status === ACTION_RESULT_STATUS.ERROR) {
|
|
50
51
|
uiLogger.error(result.reason);
|
|
51
52
|
return exit(EXIT_CODES.ERROR);
|
|
52
53
|
}
|
|
53
|
-
if (result.status ===
|
|
54
|
+
if (result.status === ACTION_RESULT_STATUS.NOOP) {
|
|
54
55
|
return exit(EXIT_CODES.SUCCESS);
|
|
55
56
|
}
|
|
56
57
|
const settingsPath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
|
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);
|
|
@@ -4,6 +4,7 @@ import { getAllConfigAccounts } from '@hubspot/local-dev-lib/config';
|
|
|
4
4
|
import { getCwd } from '@hubspot/local-dev-lib/path';
|
|
5
5
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
6
6
|
import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/local-dev-lib/config/hsSettings';
|
|
7
|
+
import { ACTION_RESULT_STATUS } from '../../types/Link.js';
|
|
7
8
|
import { ActionHandlers } from '../../lib/link/index.js';
|
|
8
9
|
import { hasDeprecatedConfigConflict, isDirectoryLinked, writeLinkedSettings, } from '../../lib/link/linkUtils.js';
|
|
9
10
|
import { commands } from '../../lang/en.js';
|
|
@@ -38,11 +39,11 @@ async function handler(args) {
|
|
|
38
39
|
},
|
|
39
40
|
args,
|
|
40
41
|
});
|
|
41
|
-
if (result.status ===
|
|
42
|
+
if (result.status === ACTION_RESULT_STATUS.ERROR) {
|
|
42
43
|
uiLogger.error(result.reason);
|
|
43
44
|
return exit(EXIT_CODES.ERROR);
|
|
44
45
|
}
|
|
45
|
-
if (result.status ===
|
|
46
|
+
if (result.status === ACTION_RESULT_STATUS.NOOP) {
|
|
46
47
|
return exit(EXIT_CODES.SUCCESS);
|
|
47
48
|
}
|
|
48
49
|
const settingsPath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
|
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,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { getConfigAccountById,
|
|
1
|
+
import { getConfigAccountById, getLinkedOrAllConfigAccounts, getConfigAccountEnvironment, } from '@hubspot/local-dev-lib/config';
|
|
2
|
+
import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/local-dev-lib/config/hsSettings';
|
|
2
3
|
import { findProjectComponents, getProjectComponentTypes, } from '../../../lib/projects/structure.js';
|
|
3
4
|
import { ComponentTypes } from '../../../types/Projects.js';
|
|
4
5
|
import { commands } from '../../../lang/en.js';
|
|
@@ -11,6 +12,7 @@ import { handleExit } from '../../../lib/process.js';
|
|
|
11
12
|
import { getErrorMessage } from '../../../lib/errorHandlers/index.js';
|
|
12
13
|
import { isSandbox, isDeveloperTestAccount, } from '../../../lib/accountTypes.js';
|
|
13
14
|
import { ensureProjectExists } from '../../../lib/projects/ensureProjectExists.js';
|
|
15
|
+
import { isDirectoryLinked, addAccountToLinkedSettings, } from '../../../lib/link/linkUtils.js';
|
|
14
16
|
export async function deprecatedProjectDevFlow({ args, accountId, projectConfig, projectDir, }) {
|
|
15
17
|
const { userProvidedAccount, derivedAccountId, exit } = args;
|
|
16
18
|
const env = getConfigAccountEnvironment(derivedAccountId);
|
|
@@ -32,7 +34,9 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
32
34
|
uiLogger.error(commands.project.dev.errors.invalidProjectComponents);
|
|
33
35
|
return exit(EXIT_CODES.SUCCESS);
|
|
34
36
|
}
|
|
35
|
-
const
|
|
37
|
+
const hsSettings = getHsSettingsFileIfExists();
|
|
38
|
+
const directoryIsLinked = isDirectoryLinked(hsSettings);
|
|
39
|
+
const accounts = getLinkedOrAllConfigAccounts();
|
|
36
40
|
if (!accounts) {
|
|
37
41
|
uiLogger.error(commands.project.dev.errors.noAccountsInConfig);
|
|
38
42
|
return exit(EXIT_CODES.ERROR);
|
|
@@ -69,6 +73,10 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
69
73
|
else {
|
|
70
74
|
await checkIfDefaultAccountIsSupported(accountConfig, hasPublicApps, exit);
|
|
71
75
|
}
|
|
76
|
+
if (directoryIsLinked) {
|
|
77
|
+
uiLogger.log('');
|
|
78
|
+
uiLogger.info(commands.account.subcommands.link.shared.usingLinkedAccounts(getHsSettingsFilePath()));
|
|
79
|
+
}
|
|
72
80
|
// The user is targeting an account type that we recommend developing on
|
|
73
81
|
if (!targetProjectAccountId && bypassRecommendedAccountPrompt) {
|
|
74
82
|
targetTestingAccountId = derivedAccountId;
|
|
@@ -101,6 +109,9 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
101
109
|
if (!accountAdded) {
|
|
102
110
|
return exit(EXIT_CODES.SUCCESS);
|
|
103
111
|
}
|
|
112
|
+
if (directoryIsLinked) {
|
|
113
|
+
addAccountToLinkedSettings(notInConfigAccount.id);
|
|
114
|
+
}
|
|
104
115
|
}
|
|
105
116
|
createNewSandbox = hasPrivateApps && createNestedAccount;
|
|
106
117
|
createNewDeveloperTestAccount = hasPublicApps && createNestedAccount;
|
|
@@ -114,6 +125,9 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
114
125
|
}
|
|
115
126
|
// We will be running our tests against this new sandbox account
|
|
116
127
|
targetTestingAccountId = targetProjectAccountId;
|
|
128
|
+
if (directoryIsLinked) {
|
|
129
|
+
addAccountToLinkedSettings(targetProjectAccountId);
|
|
130
|
+
}
|
|
117
131
|
}
|
|
118
132
|
if (createNewDeveloperTestAccount) {
|
|
119
133
|
try {
|
|
@@ -123,6 +137,9 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
123
137
|
return exit(EXIT_CODES.ERROR);
|
|
124
138
|
}
|
|
125
139
|
targetProjectAccountId = derivedAccountId;
|
|
140
|
+
if (directoryIsLinked) {
|
|
141
|
+
addAccountToLinkedSettings(targetTestingAccountId);
|
|
142
|
+
}
|
|
126
143
|
}
|
|
127
144
|
if (!targetProjectAccountId || !targetTestingAccountId) {
|
|
128
145
|
uiLogger.error(commands.project.dev.errors.noAccount(accountId));
|
|
@@ -156,6 +173,7 @@ export async function deprecatedProjectDevFlow({ args, accountId, projectConfig,
|
|
|
156
173
|
targetAccountId: targetTestingAccountId,
|
|
157
174
|
env,
|
|
158
175
|
exit,
|
|
176
|
+
port: args.port,
|
|
159
177
|
});
|
|
160
178
|
await LocalDev.start();
|
|
161
179
|
handleExit(({ isSIGHUP }) => LocalDev.stop(!isSIGHUP));
|
|
@@ -13,6 +13,7 @@ import { uiLogger } from '../../../lib/ui/logger.js';
|
|
|
13
13
|
import { logError } from '../../../lib/errorHandlers/index.js';
|
|
14
14
|
import { projectProfilePrompt } from '../../../lib/prompts/projectProfilePrompt.js';
|
|
15
15
|
import { isPromptExitError } from '../../../lib/errors/PromptExitError.js';
|
|
16
|
+
import { LOCAL_DEV_DEFAULT_PORT } from '../../../lib/constants.js';
|
|
16
17
|
const command = 'dev';
|
|
17
18
|
const describe = commands.project.dev.describe;
|
|
18
19
|
function validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV2) {
|
|
@@ -149,6 +150,11 @@ function projectDevBuilder(yargs) {
|
|
|
149
150
|
type: 'string',
|
|
150
151
|
description: commands.project.dev.options.account,
|
|
151
152
|
});
|
|
153
|
+
yargs.option('port', {
|
|
154
|
+
type: 'number',
|
|
155
|
+
description: commands.project.dev.options.port,
|
|
156
|
+
default: LOCAL_DEV_DEFAULT_PORT,
|
|
157
|
+
});
|
|
152
158
|
yargs.example([['$0 project dev', commands.project.dev.examples.default]]);
|
|
153
159
|
yargs.conflicts('profile', 'account');
|
|
154
160
|
yargs.conflicts('profile', 'testing-account');
|
|
@@ -3,7 +3,7 @@ import util from 'util';
|
|
|
3
3
|
import { HUBSPOT_ACCOUNT_TYPES } from '@hubspot/local-dev-lib/constants/config';
|
|
4
4
|
import { startPortManagerServer, stopPortManagerServer, } from '@hubspot/local-dev-lib/portManager';
|
|
5
5
|
import { isTranslationError, translateForLocalDev, } from '@hubspot/project-parsing-lib/translate';
|
|
6
|
-
import { getConfigAccountEnvironment,
|
|
6
|
+
import { getConfigAccountEnvironment, getLinkedOrAllConfigAccounts, getConfigAccountById, } from '@hubspot/local-dev-lib/config';
|
|
7
7
|
import { logError } from '../../../lib/errorHandlers/index.js';
|
|
8
8
|
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
9
9
|
import { ensureProjectExists } from '../../../lib/projects/ensureProjectExists.js';
|
|
@@ -18,6 +18,8 @@ import { uiLogger } from '../../../lib/ui/logger.js';
|
|
|
18
18
|
import { commands } from '../../../lang/en.js';
|
|
19
19
|
import LocalDevWebsocketServer from '../../../lib/projects/localDev/LocalDevWebsocketServer.js';
|
|
20
20
|
import { isLocalDevRunning } from '../../../lib/projects/localDev/helpers/process.js';
|
|
21
|
+
import { getHsSettingsFileIfExists, getHsSettingsFilePath, } from '@hubspot/local-dev-lib/config/hsSettings';
|
|
22
|
+
import { isDirectoryLinked, addAccountToLinkedSettings, } from '../../../lib/link/linkUtils.js';
|
|
21
23
|
export async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTargetTestingAccountId, projectConfig, projectDir, }) {
|
|
22
24
|
const { exit } = args;
|
|
23
25
|
if (await isLocalDevRunning()) {
|
|
@@ -56,13 +58,19 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
56
58
|
uiLogger.error(commands.project.dev.errors.noAccount(targetProjectAccountId));
|
|
57
59
|
return exit(EXIT_CODES.ERROR);
|
|
58
60
|
}
|
|
59
|
-
const
|
|
61
|
+
const hsSettings = getHsSettingsFileIfExists();
|
|
62
|
+
const directoryIsLinked = isDirectoryLinked(hsSettings);
|
|
63
|
+
const accounts = getLinkedOrAllConfigAccounts();
|
|
60
64
|
const accountIsCombined = await isUnifiedAccount(targetProjectAccountConfig);
|
|
61
65
|
const targetProjectAccountIsTestAccountOrSandbox = isTestAccountOrSandbox(targetProjectAccountConfig);
|
|
62
66
|
if (!accountIsCombined) {
|
|
63
67
|
uiLogger.error(commands.project.dev.errors.accountNotCombined);
|
|
64
68
|
return exit(EXIT_CODES.ERROR);
|
|
65
69
|
}
|
|
70
|
+
if (directoryIsLinked && !providedTargetTestingAccountId) {
|
|
71
|
+
uiLogger.log('');
|
|
72
|
+
uiLogger.info(commands.account.subcommands.link.shared.usingLinkedAccounts(getHsSettingsFilePath()));
|
|
73
|
+
}
|
|
66
74
|
let targetTestingAccountId = providedTargetTestingAccountId;
|
|
67
75
|
// Temporarily removing logic to use profile account as testing account
|
|
68
76
|
// if (profileConfig) {
|
|
@@ -90,6 +98,9 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
90
98
|
if (!accountAdded) {
|
|
91
99
|
return exit(EXIT_CODES.SUCCESS);
|
|
92
100
|
}
|
|
101
|
+
if (directoryIsLinked) {
|
|
102
|
+
addAccountToLinkedSettings(devAccountPromptResponse.notInConfigAccount.id);
|
|
103
|
+
}
|
|
93
104
|
}
|
|
94
105
|
else if (devAccountPromptResponse.createNestedAccount) {
|
|
95
106
|
// Create a new developer test account and automatically add it to the CLI config
|
|
@@ -99,6 +110,9 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
99
110
|
catch {
|
|
100
111
|
return exit(EXIT_CODES.ERROR);
|
|
101
112
|
}
|
|
113
|
+
if (directoryIsLinked) {
|
|
114
|
+
addAccountToLinkedSettings(targetTestingAccountId);
|
|
115
|
+
}
|
|
102
116
|
}
|
|
103
117
|
}
|
|
104
118
|
else if (accountType === HUBSPOT_ACCOUNT_TYPES.DEVELOPMENT_SANDBOX) {
|
|
@@ -112,6 +126,9 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
112
126
|
catch {
|
|
113
127
|
return exit(EXIT_CODES.ERROR);
|
|
114
128
|
}
|
|
129
|
+
if (directoryIsLinked) {
|
|
130
|
+
addAccountToLinkedSettings(targetTestingAccountId);
|
|
131
|
+
}
|
|
115
132
|
}
|
|
116
133
|
}
|
|
117
134
|
else {
|
|
@@ -143,7 +160,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
143
160
|
}
|
|
144
161
|
// End setup, start local dev process
|
|
145
162
|
try {
|
|
146
|
-
await startPortManagerServer();
|
|
163
|
+
await startPortManagerServer(args.port);
|
|
147
164
|
}
|
|
148
165
|
catch (e) {
|
|
149
166
|
logError(e);
|
package/commands/project/lint.js
CHANGED
|
@@ -10,7 +10,7 @@ import { logError } from '../../lib/errorHandlers/index.js';
|
|
|
10
10
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
11
11
|
import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
12
12
|
import SpinniesManager from '../../lib/ui/SpinniesManager.js';
|
|
13
|
-
import { areAllLintPackagesInstalled, getMissingLintPackages, lintPackages, displayLintResults, hasEslintConfig, hasDeprecatedEslintConfig, getDeprecatedEslintConfigFiles, createEslintConfig, REQUIRED_PACKAGES_AND_MIN_VERSIONS, } from '../../lib/projects/uieLinting.js';
|
|
13
|
+
import { areAllLintPackagesInstalled, getMissingLintPackages, getMissingLintScripts, addLintScriptsToPackageJson, lintPackages, displayLintResults, hasEslintConfig, hasDeprecatedEslintConfig, getDeprecatedEslintConfigFiles, createEslintConfig, REQUIRED_PACKAGES_AND_MIN_VERSIONS, } from '../../lib/projects/uieLinting.js';
|
|
14
14
|
const command = 'lint';
|
|
15
15
|
const describe = commands.project.lint.help.describe;
|
|
16
16
|
async function handler(args) {
|
|
@@ -133,6 +133,23 @@ async function handler(args) {
|
|
|
133
133
|
return exit(EXIT_CODES.ERROR);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
const locationsNeedingScripts = locationsReadyToLint.filter(location => getMissingLintScripts(location).length > 0);
|
|
137
|
+
if (locationsNeedingScripts.length > 0) {
|
|
138
|
+
SpinniesManager.add('lintScriptsAdd', {
|
|
139
|
+
text: commands.project.lint.loading.addingLintScripts,
|
|
140
|
+
});
|
|
141
|
+
const addedResults = [];
|
|
142
|
+
for (const location of locationsNeedingScripts) {
|
|
143
|
+
const result = addLintScriptsToPackageJson(location);
|
|
144
|
+
if (result.added.length > 0) {
|
|
145
|
+
addedResults.push(result);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
SpinniesManager.succeed('lintScriptsAdd');
|
|
149
|
+
addedResults.forEach(({ added, relativePath }) => {
|
|
150
|
+
uiLogger.success(commands.project.lint.lintScriptsAdded(added, relativePath));
|
|
151
|
+
});
|
|
152
|
+
}
|
|
136
153
|
SpinniesManager.add('lintRun', {
|
|
137
154
|
text: commands.project.lint.loading.linting,
|
|
138
155
|
});
|