@hubspot/cli 8.0.11-experimental.2 → 8.0.12-experimental.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/link.d.ts +4 -0
- package/commands/account/link.js +88 -0
- package/commands/account/unlink.d.ts +4 -0
- package/commands/account/unlink.js +69 -0
- 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/lint.js +2 -1
- package/commands/project/upload.d.ts +2 -0
- package/commands/project/upload.js +35 -3
- package/commands/project.js +2 -0
- package/lang/en.d.ts +94 -0
- package/lang/en.js +103 -4
- package/lib/app/migrate.js +2 -1
- package/lib/link/accountTableUtils.d.ts +10 -0
- package/lib/link/accountTableUtils.js +39 -0
- package/lib/link/index.d.ts +14 -0
- package/lib/link/index.js +154 -0
- package/lib/link/linkUtils.d.ts +4 -0
- package/lib/link/linkUtils.js +24 -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/projects/ProjectLogsManager.js +4 -1
- package/lib/projects/preview.d.ts +7 -0
- package/lib/projects/preview.js +71 -0
- package/lib/projects/uieLinting.d.ts +8 -3
- package/lib/projects/uieLinting.js +48 -27
- package/lib/projects/upload.d.ts +1 -0
- package/lib/projects/upload.js +4 -3
- package/lib/prompts/projectsLogsPrompt.js +3 -0
- package/lib/prompts/promptUtils.js +1 -0
- package/mcp-server/server.js +35 -1
- package/package.json +7 -7
- package/types/Link.d.ts +27 -0
- package/types/Link.js +1 -0
- package/types/Prompts.d.ts +1 -0
|
@@ -0,0 +1,88 @@
|
|
|
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 { handleLinkFlow } from '../../lib/link/index.js';
|
|
11
|
+
import { hasDeprecatedConfigConflict, writeLinkedSettings, } from '../../lib/link/linkUtils.js';
|
|
12
|
+
import { renderLinkedAccountsTable } from '../../lib/link/renderLinkedAccountsTable.js';
|
|
13
|
+
import { commands } from '../../lang/en.js';
|
|
14
|
+
import { debugError } from '../../lib/errorHandlers/index.js';
|
|
15
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
16
|
+
const command = 'link';
|
|
17
|
+
// Hide the command until we're done testing and ready to make linking GA
|
|
18
|
+
// const describe = commands.account.subcommands.link.describe;
|
|
19
|
+
const describe = undefined;
|
|
20
|
+
async function handler(args) {
|
|
21
|
+
const { exit } = args;
|
|
22
|
+
if (hasDeprecatedConfigConflict(args._)) {
|
|
23
|
+
return exit(EXIT_CODES.ERROR);
|
|
24
|
+
}
|
|
25
|
+
const existingSettings = getHsSettingsFileIfExists();
|
|
26
|
+
const isNewFile = existingSettings === null;
|
|
27
|
+
if (isNewFile) {
|
|
28
|
+
uiLogger.log(commands.account.subcommands.link.linkingDirectory(getCwd()));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
uiLogger.log(commands.account.subcommands.link.managingLinkedAccounts(getCwd()));
|
|
32
|
+
}
|
|
33
|
+
uiLogger.log('');
|
|
34
|
+
const settingsFilePath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
|
|
35
|
+
uiLogger.log(commands.account.subcommands.link.settingsInfo(settingsFilePath));
|
|
36
|
+
uiLogger.log('');
|
|
37
|
+
const settings = isNewFile ? EMPTY_HS_SETTINGS_FILE : existingSettings;
|
|
38
|
+
const accounts = getAllConfigAccounts();
|
|
39
|
+
const accountOverrideId = getDefaultAccountOverrideAccountId(accounts);
|
|
40
|
+
if (settings.accounts.length !== 0) {
|
|
41
|
+
await renderLinkedAccountsTable(settings);
|
|
42
|
+
uiLogger.log('');
|
|
43
|
+
}
|
|
44
|
+
const result = await handleLinkFlow({
|
|
45
|
+
settings,
|
|
46
|
+
accountOverrideId,
|
|
47
|
+
args,
|
|
48
|
+
});
|
|
49
|
+
if (result.status === 'error') {
|
|
50
|
+
uiLogger.error(result.reason);
|
|
51
|
+
return exit(EXIT_CODES.ERROR);
|
|
52
|
+
}
|
|
53
|
+
if (result.status === 'noop') {
|
|
54
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
55
|
+
}
|
|
56
|
+
const settingsPath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
|
|
57
|
+
if (!writeLinkedSettings(result.settings, settingsPath)) {
|
|
58
|
+
return exit(EXIT_CODES.ERROR);
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
checkAndAddHsFolderToGitignore(settingsPath);
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
debugError(e);
|
|
65
|
+
}
|
|
66
|
+
if (isNewFile) {
|
|
67
|
+
uiLogger.success(commands.account.subcommands.link.success.created(settingsPath));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
uiLogger.success(commands.account.subcommands.link.shared.savedToSettings(settingsPath));
|
|
71
|
+
}
|
|
72
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
73
|
+
}
|
|
74
|
+
function linkBuilder(yargs) {
|
|
75
|
+
yargs.example([['$0 link']]);
|
|
76
|
+
return yargs;
|
|
77
|
+
}
|
|
78
|
+
const builder = makeYargsBuilder(linkBuilder, command, commands.account.subcommands.link.verboseDescribe, {
|
|
79
|
+
useGlobalOptions: true,
|
|
80
|
+
useConfigOptions: true,
|
|
81
|
+
});
|
|
82
|
+
const linkCommand = {
|
|
83
|
+
command,
|
|
84
|
+
describe,
|
|
85
|
+
handler: makeYargsHandlerWithUsageTracking('account-link', handler),
|
|
86
|
+
builder,
|
|
87
|
+
};
|
|
88
|
+
export default linkCommand;
|
|
@@ -0,0 +1,69 @@
|
|
|
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 { ActionHandlers } from '../../lib/link/index.js';
|
|
8
|
+
import { hasDeprecatedConfigConflict, isDirectoryLinked, writeLinkedSettings, } from '../../lib/link/linkUtils.js';
|
|
9
|
+
import { commands } from '../../lang/en.js';
|
|
10
|
+
import { DEFAULT_HS_SETTINGS_PATH } from '@hubspot/local-dev-lib/constants/config';
|
|
11
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
12
|
+
const command = 'unlink';
|
|
13
|
+
// Hide the command until we're done testing and ready to make linking GA
|
|
14
|
+
// const describe = commands.account.subcommands.link.describe;
|
|
15
|
+
const describe = undefined;
|
|
16
|
+
async function handler(args) {
|
|
17
|
+
const { exit } = args;
|
|
18
|
+
if (hasDeprecatedConfigConflict(args._)) {
|
|
19
|
+
return exit(EXIT_CODES.ERROR);
|
|
20
|
+
}
|
|
21
|
+
const existingSettings = getHsSettingsFileIfExists();
|
|
22
|
+
if (!isDirectoryLinked(existingSettings)) {
|
|
23
|
+
const globalAccounts = getAllConfigAccounts();
|
|
24
|
+
uiLogger.log(commands.account.subcommands.link.shared.noLinkedAccounts);
|
|
25
|
+
uiLogger.log(commands.account.subcommands.link.shared.globalAccountsAvailable(globalAccounts.length));
|
|
26
|
+
uiLogger.log('');
|
|
27
|
+
uiLogger.log(commands.account.subcommands.link.shared.configurePrompt);
|
|
28
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
29
|
+
}
|
|
30
|
+
uiLogger.log(commands.account.subcommands.link.managingLinkedAccounts(getCwd()));
|
|
31
|
+
uiLogger.log('');
|
|
32
|
+
const result = await ActionHandlers.unlink({
|
|
33
|
+
state: existingSettings,
|
|
34
|
+
context: {
|
|
35
|
+
globalAccountsList: getAllConfigAccounts(),
|
|
36
|
+
globalDefaultAccount: undefined,
|
|
37
|
+
accountOverrideId: null,
|
|
38
|
+
},
|
|
39
|
+
args,
|
|
40
|
+
});
|
|
41
|
+
if (result.status === 'error') {
|
|
42
|
+
uiLogger.error(result.reason);
|
|
43
|
+
return exit(EXIT_CODES.ERROR);
|
|
44
|
+
}
|
|
45
|
+
if (result.status === 'noop') {
|
|
46
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
47
|
+
}
|
|
48
|
+
const settingsPath = getHsSettingsFilePath() || DEFAULT_HS_SETTINGS_PATH;
|
|
49
|
+
if (!writeLinkedSettings(result.settings, settingsPath)) {
|
|
50
|
+
return exit(EXIT_CODES.ERROR);
|
|
51
|
+
}
|
|
52
|
+
uiLogger.success(commands.account.subcommands.link.shared.savedToSettings(settingsPath));
|
|
53
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
54
|
+
}
|
|
55
|
+
function unlinkBuilder(yargs) {
|
|
56
|
+
yargs.example([['$0 account unlink']]);
|
|
57
|
+
return yargs;
|
|
58
|
+
}
|
|
59
|
+
const builder = makeYargsBuilder(unlinkBuilder, command, commands.account.subcommands.unlink.verboseDescribe, {
|
|
60
|
+
useGlobalOptions: true,
|
|
61
|
+
useConfigOptions: true,
|
|
62
|
+
});
|
|
63
|
+
const unlinkCommand = {
|
|
64
|
+
command,
|
|
65
|
+
describe,
|
|
66
|
+
handler: makeYargsHandlerWithUsageTracking('account-unlink', handler),
|
|
67
|
+
builder,
|
|
68
|
+
};
|
|
69
|
+
export default unlinkCommand;
|
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;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fetchAppInstallationData } from '@hubspot/local-dev-lib/api/localDevAuth';
|
|
3
|
+
import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
|
|
4
|
+
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
5
|
+
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
6
|
+
import { translateForLocalDev } from '@hubspot/project-parsing-lib/translate';
|
|
7
|
+
import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
|
|
8
|
+
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
9
|
+
import { uiLogger } from '../../lib/ui/logger.js';
|
|
10
|
+
import { ApiErrorContext, debugError, logError, } from '../../lib/errorHandlers/index.js';
|
|
11
|
+
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
12
|
+
import { commands } from '../../lang/en.js';
|
|
13
|
+
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
14
|
+
import { isAppIRNode } from '../../lib/projects/structure.js';
|
|
15
|
+
import { APP_AUTH_TYPES } from '../../lib/constants.js';
|
|
16
|
+
const command = 'app-install-status';
|
|
17
|
+
const describe = commands.project.installStatus.describe;
|
|
18
|
+
async function handler(args) {
|
|
19
|
+
const { derivedAccountId, formatOutputAsJson, exit } = args;
|
|
20
|
+
const { projectConfig, projectDir } = await getProjectConfig();
|
|
21
|
+
if (!projectConfig || !projectDir) {
|
|
22
|
+
uiLogger.error(commands.project.installStatus.errors.noProjectConfig);
|
|
23
|
+
return exit(EXIT_CODES.ERROR);
|
|
24
|
+
}
|
|
25
|
+
if (isLegacyProject(projectConfig.platformVersion)) {
|
|
26
|
+
uiLogger.error(commands.project.installStatus.errors.unsupportedPlatformVersion(projectConfig.platformVersion));
|
|
27
|
+
return exit(EXIT_CODES.ERROR);
|
|
28
|
+
}
|
|
29
|
+
let appNode;
|
|
30
|
+
try {
|
|
31
|
+
const { intermediateNodesIndexedByUid } = await translateForLocalDev({
|
|
32
|
+
projectSourceDir: path.join(projectDir, projectConfig.srcDir),
|
|
33
|
+
platformVersion: projectConfig.platformVersion,
|
|
34
|
+
accountId: derivedAccountId,
|
|
35
|
+
}, { skipValidation: true });
|
|
36
|
+
appNode = Object.values(intermediateNodesIndexedByUid).find(isAppIRNode);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
debugError(error);
|
|
40
|
+
uiLogger.error(commands.project.installStatus.errors.failedToParseProject);
|
|
41
|
+
return exit(EXIT_CODES.ERROR);
|
|
42
|
+
}
|
|
43
|
+
if (!appNode) {
|
|
44
|
+
uiLogger.error(commands.project.installStatus.errors.noAppInProject);
|
|
45
|
+
return exit(EXIT_CODES.ERROR);
|
|
46
|
+
}
|
|
47
|
+
if (appNode.config.auth.type.toLowerCase() !== APP_AUTH_TYPES.STATIC) {
|
|
48
|
+
uiLogger.error(commands.project.installStatus.errors.unsupportedAuthType(appNode.config.auth.type));
|
|
49
|
+
return exit(EXIT_CODES.ERROR);
|
|
50
|
+
}
|
|
51
|
+
let projectId;
|
|
52
|
+
try {
|
|
53
|
+
const response = await fetchProject(derivedAccountId, projectConfig.name);
|
|
54
|
+
projectId = response.data.id;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
logError(error, new ApiErrorContext({
|
|
58
|
+
accountId: derivedAccountId,
|
|
59
|
+
projectName: projectConfig.name,
|
|
60
|
+
}));
|
|
61
|
+
return exit(EXIT_CODES.ERROR);
|
|
62
|
+
}
|
|
63
|
+
let isInstalledWithScopeGroups = false;
|
|
64
|
+
let previouslyAuthorizedScopeGroups = [];
|
|
65
|
+
let appId;
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetchAppInstallationData(derivedAccountId, projectId, appNode.uid, appNode.config.auth.requiredScopes, appNode.config.auth.optionalScopes);
|
|
68
|
+
isInstalledWithScopeGroups = response.data.isInstalledWithScopeGroups;
|
|
69
|
+
previouslyAuthorizedScopeGroups =
|
|
70
|
+
response.data.previouslyAuthorizedScopeGroups;
|
|
71
|
+
appId = response.data.appId;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (!isHubSpotHttpError(error) || error.status !== 404) {
|
|
75
|
+
logError(error, new ApiErrorContext({
|
|
76
|
+
accountId: derivedAccountId,
|
|
77
|
+
projectName: projectConfig.name,
|
|
78
|
+
}));
|
|
79
|
+
return exit(EXIT_CODES.ERROR);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const isInstalled = isInstalledWithScopeGroups || previouslyAuthorizedScopeGroups.length > 0;
|
|
83
|
+
if (formatOutputAsJson) {
|
|
84
|
+
uiLogger.json({
|
|
85
|
+
appId,
|
|
86
|
+
appUid: appNode.uid,
|
|
87
|
+
accountId: derivedAccountId,
|
|
88
|
+
projectId,
|
|
89
|
+
isInstalled,
|
|
90
|
+
isInstalledWithCurrentScopes: isInstalledWithScopeGroups,
|
|
91
|
+
previouslyAuthorizedScopeGroups,
|
|
92
|
+
});
|
|
93
|
+
return exit(isInstalled ? EXIT_CODES.SUCCESS : EXIT_CODES.WARNING);
|
|
94
|
+
}
|
|
95
|
+
if (isInstalled) {
|
|
96
|
+
if (isInstalledWithScopeGroups) {
|
|
97
|
+
uiLogger.success(commands.project.installStatus.success.installed(appNode.config.name, derivedAccountId));
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
uiLogger.success(commands.project.installStatus.success.installedWithOutdatedScopes(appNode.config.name, derivedAccountId));
|
|
101
|
+
}
|
|
102
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
103
|
+
}
|
|
104
|
+
uiLogger.log(commands.project.installStatus.notInstalled(appNode.config.name, derivedAccountId));
|
|
105
|
+
return exit(EXIT_CODES.WARNING);
|
|
106
|
+
}
|
|
107
|
+
function projectInstallStatusBuilder(yargs) {
|
|
108
|
+
yargs.example([
|
|
109
|
+
[
|
|
110
|
+
'$0 project app-install-status',
|
|
111
|
+
commands.project.installStatus.examples.default,
|
|
112
|
+
],
|
|
113
|
+
[
|
|
114
|
+
'$0 project app-install-status --json',
|
|
115
|
+
commands.project.installStatus.examples.json,
|
|
116
|
+
],
|
|
117
|
+
]);
|
|
118
|
+
return yargs;
|
|
119
|
+
}
|
|
120
|
+
const builder = makeYargsBuilder(projectInstallStatusBuilder, command, describe, {
|
|
121
|
+
useGlobalOptions: true,
|
|
122
|
+
useConfigOptions: true,
|
|
123
|
+
useAccountOptions: true,
|
|
124
|
+
useJSONOutputOptions: true,
|
|
125
|
+
});
|
|
126
|
+
const projectInstallStatusCommand = {
|
|
127
|
+
command,
|
|
128
|
+
describe,
|
|
129
|
+
handler: makeYargsHandlerWithUsageTracking('project-app-install-status', handler),
|
|
130
|
+
builder,
|
|
131
|
+
};
|
|
132
|
+
export default projectInstallStatusCommand;
|
|
@@ -19,8 +19,15 @@ import { updateHsMetaFilesWithAutoGeneratedFields } from '../../lib/projects/com
|
|
|
19
19
|
import SpinniesManager from '../../lib/ui/SpinniesManager.js';
|
|
20
20
|
const command = ['create', 'init'];
|
|
21
21
|
const describe = commands.project.create.describe;
|
|
22
|
+
const BETA_VERSIONS = [
|
|
23
|
+
PLATFORM_VERSIONS.v2026_09_BETA,
|
|
24
|
+
PLATFORM_VERSIONS.v2026_03_BETA,
|
|
25
|
+
];
|
|
22
26
|
async function handler(args) {
|
|
23
27
|
const { platformVersion, templateSource, exit, addUsageMetadata } = args;
|
|
28
|
+
if (BETA_VERSIONS.includes(platformVersion)) {
|
|
29
|
+
uiLogger.warn(commands.project.create.warnings.betaPlatformVersion(platformVersion));
|
|
30
|
+
}
|
|
24
31
|
if (templateSource && !templateSource.includes('/')) {
|
|
25
32
|
uiLogger.error(commands.project.create.errors.invalidTemplateSource);
|
|
26
33
|
return exit(EXIT_CODES.ERROR);
|
|
@@ -128,6 +135,7 @@ function projectCreateBuilder(yargs) {
|
|
|
128
135
|
PLATFORM_VERSIONS.v2025_2,
|
|
129
136
|
PLATFORM_VERSIONS.v2026_03_BETA,
|
|
130
137
|
PLATFORM_VERSIONS.v2026_03,
|
|
138
|
+
PLATFORM_VERSIONS.v2026_09_BETA,
|
|
131
139
|
],
|
|
132
140
|
default: PLATFORM_VERSIONS.v2026_03,
|
|
133
141
|
},
|
package/commands/project/lint.js
CHANGED
|
@@ -117,9 +117,10 @@ async function handler(args) {
|
|
|
117
117
|
SpinniesManager.add('lintConfigCreate', {
|
|
118
118
|
text: commands.project.lint.loading.creatingConfig,
|
|
119
119
|
});
|
|
120
|
+
const platformVersion = projectConfig.projectConfig?.platformVersion ?? null;
|
|
120
121
|
const createdConfigs = [];
|
|
121
122
|
for (const location of locationsNeedingConfig) {
|
|
122
|
-
const configPath = createEslintConfig(location);
|
|
123
|
+
const configPath = await createEslintConfig(location, platformVersion);
|
|
123
124
|
createdConfigs.push(configPath);
|
|
124
125
|
}
|
|
125
126
|
SpinniesManager.succeed('lintConfigCreate');
|
|
@@ -5,6 +5,8 @@ export type ProjectUploadArgs = CommonArgs & JSONOutputArgs & {
|
|
|
5
5
|
m: string;
|
|
6
6
|
skipValidation: boolean;
|
|
7
7
|
profile?: string;
|
|
8
|
+
preview: boolean;
|
|
9
|
+
target?: number;
|
|
8
10
|
};
|
|
9
11
|
declare const projectUploadCommand: YargsCommandModule<unknown, ProjectUploadArgs>;
|
|
10
12
|
export default projectUploadCommand;
|
|
@@ -8,7 +8,8 @@ import { logFeedbackMessage } from '../../lib/projects/ui.js';
|
|
|
8
8
|
import { handleProjectUpload } from '../../lib/projects/upload.js';
|
|
9
9
|
import { loadAndValidateProfile } from '../../lib/projects/projectProfiles.js';
|
|
10
10
|
import { displayWarnLogs, pollProjectBuildAndDeploy, } from '../../lib/projects/pollProjectBuildAndDeploy.js';
|
|
11
|
-
import {
|
|
11
|
+
import { triggerAndPollPreview } from '../../lib/projects/preview.js';
|
|
12
|
+
import { commands, lib } from '../../lang/en.js';
|
|
12
13
|
import { PROJECT_ERROR_TYPES } from '../../lib/constants.js';
|
|
13
14
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
14
15
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
@@ -18,7 +19,7 @@ import { projectProfilePrompt } from '../../lib/prompts/projectProfilePrompt.js'
|
|
|
18
19
|
const command = 'upload';
|
|
19
20
|
const describe = commands.project.upload.describe;
|
|
20
21
|
async function handler(args) {
|
|
21
|
-
const { forceCreate, message, derivedAccountId, skipValidation, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, exit, addUsageMetadata, } = args;
|
|
22
|
+
const { forceCreate, message, derivedAccountId, skipValidation, formatOutputAsJson, profile: profileOption, useEnv: useEnvOption, preview, target: targetPortalId, exit, addUsageMetadata, } = args;
|
|
22
23
|
const jsonOutput = {};
|
|
23
24
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
24
25
|
try {
|
|
@@ -56,7 +57,7 @@ async function handler(args) {
|
|
|
56
57
|
assetType: projectConfig.platformVersion,
|
|
57
58
|
});
|
|
58
59
|
try {
|
|
59
|
-
const { result, uploadError } = await handleProjectUpload({
|
|
60
|
+
const { result, uploadError, projectId } = await handleProjectUpload({
|
|
60
61
|
accountId: targetAccountId,
|
|
61
62
|
projectConfig,
|
|
62
63
|
projectDir,
|
|
@@ -90,6 +91,23 @@ async function handler(args) {
|
|
|
90
91
|
logFeedbackMessage(result.buildId);
|
|
91
92
|
await displayWarnLogs(targetAccountId, projectConfig.name, result.buildId);
|
|
92
93
|
}
|
|
94
|
+
if (result && result.succeeded && preview && targetPortalId) {
|
|
95
|
+
if (!projectId) {
|
|
96
|
+
uiLogger.warn(lib.projectPreview.missingProjectId);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
const previewResult = await triggerAndPollPreview(targetAccountId, projectId, result.buildId, targetPortalId);
|
|
100
|
+
if (!previewResult.succeeded) {
|
|
101
|
+
uiLogger.warn(lib.projectPreview.warning);
|
|
102
|
+
}
|
|
103
|
+
if (formatOutputAsJson) {
|
|
104
|
+
jsonOutput.preview = {
|
|
105
|
+
releaseTag: previewResult.releaseTag,
|
|
106
|
+
succeeded: previewResult.succeeded,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
93
111
|
if (result && result.succeeded && formatOutputAsJson) {
|
|
94
112
|
jsonOutput.buildId = result.buildId;
|
|
95
113
|
if (result.deployResult) {
|
|
@@ -132,14 +150,28 @@ function projectUploadBuilder(yargs) {
|
|
|
132
150
|
alias: 'p',
|
|
133
151
|
describe: commands.project.upload.options.profile.describe,
|
|
134
152
|
},
|
|
153
|
+
preview: {
|
|
154
|
+
describe: commands.project.upload.options.preview.describe,
|
|
155
|
+
type: 'boolean',
|
|
156
|
+
default: false,
|
|
157
|
+
},
|
|
158
|
+
target: {
|
|
159
|
+
describe: commands.project.upload.options.target.describe,
|
|
160
|
+
type: 'number',
|
|
161
|
+
},
|
|
135
162
|
});
|
|
136
163
|
yargs.conflicts('profile', 'account');
|
|
164
|
+
yargs.implies('preview', 'target');
|
|
137
165
|
yargs.example([
|
|
138
166
|
['$0 project upload', commands.project.upload.examples.default],
|
|
139
167
|
[
|
|
140
168
|
'$0 project upload --profile=profileName',
|
|
141
169
|
commands.project.upload.examples.withProfile,
|
|
142
170
|
],
|
|
171
|
+
[
|
|
172
|
+
'$0 project upload --preview --target=12345',
|
|
173
|
+
commands.project.upload.examples.withPreview,
|
|
174
|
+
],
|
|
143
175
|
]);
|
|
144
176
|
return yargs;
|
|
145
177
|
}
|
package/commands/project.js
CHANGED
|
@@ -19,6 +19,7 @@ import projectValidate from './project/validate.js';
|
|
|
19
19
|
import list from './project/list.js';
|
|
20
20
|
import info from './project/info.js';
|
|
21
21
|
import deleteProject from './project/delete.js';
|
|
22
|
+
import appInstallStatus from './project/appInstallStatus.js';
|
|
22
23
|
import { makeYargsBuilder } from '../lib/yargsUtils.js';
|
|
23
24
|
import { getProjectConfig } from '../lib/projects/config.js';
|
|
24
25
|
import { isSupportedPlatformVersion, LATEST_SUPPORTED_PLATFORM_VERSION, } from '@hubspot/project-parsing-lib/projects';
|
|
@@ -66,6 +67,7 @@ function projectBuilder(yargs) {
|
|
|
66
67
|
.command(updateDeps)
|
|
67
68
|
.command(profile)
|
|
68
69
|
.command(projectValidate)
|
|
70
|
+
.command(appInstallStatus)
|
|
69
71
|
.demandCommand(1, '');
|
|
70
72
|
return yargs;
|
|
71
73
|
}
|
package/lang/en.d.ts
CHANGED
|
@@ -178,6 +178,58 @@ export declare const commands: {
|
|
|
178
178
|
defaultAccountUpdated: (accountName: string) => string;
|
|
179
179
|
};
|
|
180
180
|
};
|
|
181
|
+
link: {
|
|
182
|
+
describe: string;
|
|
183
|
+
verboseDescribe: string;
|
|
184
|
+
shared: {
|
|
185
|
+
noLinkedAccounts: string;
|
|
186
|
+
globalAccountsAvailable: (count: number) => string;
|
|
187
|
+
configurePrompt: string;
|
|
188
|
+
deprecatedConfigNotSupported: (command: string) => string;
|
|
189
|
+
writeSettingsFailed: (path: string, err: unknown) => string;
|
|
190
|
+
savedToSettings: (path: string) => string;
|
|
191
|
+
};
|
|
192
|
+
linkingDirectory: (dir: string) => string;
|
|
193
|
+
managingLinkedAccounts: (dir: string) => string;
|
|
194
|
+
settingsInfo: (path: string) => string;
|
|
195
|
+
success: {
|
|
196
|
+
created: (path: string) => string;
|
|
197
|
+
};
|
|
198
|
+
errors: {
|
|
199
|
+
authFailed: string;
|
|
200
|
+
};
|
|
201
|
+
events: {
|
|
202
|
+
accountsLinked: (count: number) => string;
|
|
203
|
+
accountsUnlinked: (count: number) => string;
|
|
204
|
+
overrideAccountDetected: (accountId: number) => string;
|
|
205
|
+
defaultAccountSet: (accountId: number) => string;
|
|
206
|
+
defaultAccountRemoved: (isSelectionRequired: boolean) => string;
|
|
207
|
+
defaultAccountRemains: (accountId: number) => string;
|
|
208
|
+
updatedLinkedAccounts: string;
|
|
209
|
+
noAccountsLinked: string;
|
|
210
|
+
overrideFileRemoved: string;
|
|
211
|
+
invalidDefaultAccount: (accountId: number) => string;
|
|
212
|
+
};
|
|
213
|
+
prompts: {
|
|
214
|
+
howToProceed: string;
|
|
215
|
+
whatToDo: string;
|
|
216
|
+
linkExisting: string;
|
|
217
|
+
authenticateNew: string;
|
|
218
|
+
cancel: string;
|
|
219
|
+
selectDefault: string;
|
|
220
|
+
selectToLink: string;
|
|
221
|
+
selectToUnlink: string;
|
|
222
|
+
alreadyLinked: string;
|
|
223
|
+
fromHsAccount: string;
|
|
224
|
+
newlyAuthenticated: string;
|
|
225
|
+
mustSelectOne: string;
|
|
226
|
+
keepAsDefault: string;
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
unlink: {
|
|
230
|
+
describe: string;
|
|
231
|
+
verboseDescribe: string;
|
|
232
|
+
};
|
|
181
233
|
remove: {
|
|
182
234
|
describe: string;
|
|
183
235
|
logs: {
|
|
@@ -1458,6 +1510,9 @@ export declare const commands: {
|
|
|
1458
1510
|
failedToFetchProjectList: string;
|
|
1459
1511
|
cannotNestProjects: (projectDir: string) => string;
|
|
1460
1512
|
};
|
|
1513
|
+
warnings: {
|
|
1514
|
+
betaPlatformVersion: (platformVersion: string) => string;
|
|
1515
|
+
};
|
|
1461
1516
|
logs: {
|
|
1462
1517
|
success: (projectName: string, projectDest: string) => string;
|
|
1463
1518
|
};
|
|
@@ -1684,6 +1739,7 @@ export declare const commands: {
|
|
|
1684
1739
|
noFunctionsLinkText: string;
|
|
1685
1740
|
noFunctionsInProject: string;
|
|
1686
1741
|
noFunctionWithName: (name: string) => string;
|
|
1742
|
+
functionNameRequired: string;
|
|
1687
1743
|
functionNotDeployed: (name: string) => string;
|
|
1688
1744
|
projectLogsManagerNotInitialized: string;
|
|
1689
1745
|
noDeployedBuild: string;
|
|
@@ -1729,6 +1785,7 @@ export declare const commands: {
|
|
|
1729
1785
|
examples: {
|
|
1730
1786
|
default: string;
|
|
1731
1787
|
withProfile: string;
|
|
1788
|
+
withPreview: string;
|
|
1732
1789
|
};
|
|
1733
1790
|
logs: {
|
|
1734
1791
|
buildSucceeded: (buildId: number) => string;
|
|
@@ -1750,6 +1807,12 @@ export declare const commands: {
|
|
|
1750
1807
|
profile: {
|
|
1751
1808
|
describe: string;
|
|
1752
1809
|
};
|
|
1810
|
+
preview: {
|
|
1811
|
+
describe: string;
|
|
1812
|
+
};
|
|
1813
|
+
target: {
|
|
1814
|
+
describe: string;
|
|
1815
|
+
};
|
|
1753
1816
|
};
|
|
1754
1817
|
};
|
|
1755
1818
|
watch: {
|
|
@@ -1876,6 +1939,8 @@ export declare const commands: {
|
|
|
1876
1939
|
}[]) => string;
|
|
1877
1940
|
createEslintConfigPrompt: (directories: string[]) => string;
|
|
1878
1941
|
eslintConfigCreated: (configPath: string) => string;
|
|
1942
|
+
createEslintConfigRequiresV2Platform: (platformVersion?: string | null) => string;
|
|
1943
|
+
failedToFetchRemoteEslintConfig: (platformVersion: string) => string;
|
|
1879
1944
|
failedToCreateEslintConfig: (configPath: string) => string;
|
|
1880
1945
|
eslintConfigRequired: string;
|
|
1881
1946
|
};
|
|
@@ -2009,6 +2074,25 @@ export declare const commands: {
|
|
|
2009
2074
|
force: string;
|
|
2010
2075
|
};
|
|
2011
2076
|
};
|
|
2077
|
+
installStatus: {
|
|
2078
|
+
describe: string;
|
|
2079
|
+
examples: {
|
|
2080
|
+
default: string;
|
|
2081
|
+
json: string;
|
|
2082
|
+
};
|
|
2083
|
+
errors: {
|
|
2084
|
+
noProjectConfig: string;
|
|
2085
|
+
unsupportedPlatformVersion: (platformVersion: string) => string;
|
|
2086
|
+
failedToParseProject: string;
|
|
2087
|
+
noAppInProject: string;
|
|
2088
|
+
unsupportedAuthType: (authType: string) => string;
|
|
2089
|
+
};
|
|
2090
|
+
success: {
|
|
2091
|
+
installed: (appName: string, accountId: number) => string;
|
|
2092
|
+
installedWithOutdatedScopes: (appName: string, accountId: number) => string;
|
|
2093
|
+
};
|
|
2094
|
+
notInstalled: (appName: string, accountId: number) => string;
|
|
2095
|
+
};
|
|
2012
2096
|
};
|
|
2013
2097
|
sandbox: {
|
|
2014
2098
|
describe: string;
|
|
@@ -3290,6 +3374,16 @@ export declare const lib: {
|
|
|
3290
3374
|
updatedFileDependency: (packageName: string, relativePath: string) => string;
|
|
3291
3375
|
};
|
|
3292
3376
|
};
|
|
3377
|
+
projectPreview: {
|
|
3378
|
+
triggeringPreview: (buildId: number, targetPortalId: number) => string;
|
|
3379
|
+
pollingStatus: (releaseTag: string, targetPortalId: number) => string;
|
|
3380
|
+
succeeded: (releaseTag: string, targetPortalId: number) => string;
|
|
3381
|
+
triggerFailed: string;
|
|
3382
|
+
pollFailed: string;
|
|
3383
|
+
timeout: string;
|
|
3384
|
+
warning: string;
|
|
3385
|
+
missingProjectId: string;
|
|
3386
|
+
};
|
|
3293
3387
|
importData: {
|
|
3294
3388
|
errors: {
|
|
3295
3389
|
incorrectAccountType: (derivedAccountId: number) => string;
|