@hubspot/cli 8.14.0 → 8.15.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/cms/theme/preview.js +8 -1
- package/commands/getStarted.js +15 -20
- package/commands/project/add.js +7 -6
- package/commands/project/appInstallStatus.d.ts +1 -1
- package/commands/project/appInstallStatus.js +8 -4
- package/commands/project/create.js +20 -6
- package/commands/project/delete.js +1 -1
- package/commands/project/deploy.d.ts +1 -1
- package/commands/project/deploy.js +14 -12
- package/commands/project/dev/index.js +4 -7
- package/commands/project/download.js +3 -3
- package/commands/project/info.d.ts +1 -1
- package/commands/project/info.js +8 -5
- package/commands/project/installApp.d.ts +1 -1
- package/commands/project/installApp.js +9 -4
- package/commands/project/installDeps.js +6 -5
- package/commands/project/lint.js +16 -9
- package/commands/project/list.d.ts +3 -2
- package/commands/project/list.js +21 -3
- package/commands/project/listBuilds.d.ts +1 -1
- package/commands/project/listBuilds.js +4 -8
- package/commands/project/migrate.js +14 -12
- package/commands/project/open.js +15 -7
- package/commands/project/profile/add.js +8 -4
- package/commands/project/profile/delete.js +8 -4
- package/commands/project/release/create.d.ts +1 -1
- package/commands/project/release/create.js +5 -7
- package/commands/project/release/info.d.ts +1 -1
- package/commands/project/release/info.js +4 -4
- package/commands/project/release/list.d.ts +1 -1
- package/commands/project/release/list.js +4 -4
- package/commands/project/updateDeps.js +6 -5
- package/commands/project/upload.d.ts +1 -1
- package/commands/project/upload.js +26 -15
- package/commands/project/validate.js +14 -97
- package/commands/project/watch.js +8 -11
- package/commands/project.js +1 -1
- package/commands/testAccount/create.d.ts +1 -1
- package/commands/testAccount/create.js +1 -1
- package/lang/en.d.ts +7 -18
- package/lang/en.js +7 -18
- package/lib/app/migrate.js +5 -7
- package/lib/dependencyManagement.js +3 -10
- package/lib/doctor/DiagnosticInfoBuilder.d.ts +2 -2
- package/lib/doctor/DiagnosticInfoBuilder.js +8 -8
- package/lib/doctor/Doctor.js +7 -9
- package/lib/errors/ProjectErrors.d.ts +0 -6
- package/lib/errors/ProjectErrors.js +0 -12
- package/lib/errors/ProjectValidationError.d.ts +2 -1
- package/lib/errors/ProjectValidationError.js +3 -1
- package/lib/getStartedV2Actions.js +14 -18
- package/lib/jsonOutput/appInstallStatus.d.ts +14 -0
- package/lib/jsonOutput/appInstallStatus.js +14 -0
- package/lib/jsonOutput/createTestAccount.d.ts +7 -0
- package/lib/jsonOutput/createTestAccount.js +6 -0
- package/lib/jsonOutput/deploy.d.ts +5 -0
- package/lib/jsonOutput/deploy.js +4 -0
- package/lib/jsonOutput/info.d.ts +21 -0
- package/lib/jsonOutput/info.js +19 -0
- package/lib/jsonOutput/installApp.d.ts +11 -0
- package/lib/jsonOutput/installApp.js +10 -0
- package/lib/jsonOutput/listBuilds.d.ts +75 -0
- package/lib/jsonOutput/listBuilds.js +65 -0
- package/lib/jsonOutput/projectList.d.ts +29 -0
- package/lib/jsonOutput/projectList.js +28 -0
- package/lib/jsonOutput/release.d.ts +42 -0
- package/lib/jsonOutput/release.js +37 -0
- package/lib/jsonOutput/upload.d.ts +29 -0
- package/lib/jsonOutput/upload.js +23 -0
- package/lib/npm/packageJson.js +1 -1
- package/lib/projects/ProjectLogsManager.js +1 -4
- package/lib/projects/config.d.ts +6 -5
- package/lib/projects/config.js +7 -38
- package/lib/projects/create/tracking.d.ts +1 -0
- package/lib/projects/create/tracking.js +27 -0
- package/lib/projects/delete.js +14 -1
- package/lib/projects/localDev/LocalDevProcess.js +7 -7
- package/lib/projects/projectProfiles.d.ts +2 -2
- package/lib/projects/projectProfiles.js +0 -3
- package/lib/projects/release.js +1 -1
- package/lib/projects/uieLinting.js +0 -3
- package/lib/projects/validate.d.ts +9 -0
- package/lib/projects/validate.js +96 -0
- package/lib/theme/migrate.js +1 -4
- package/mcp-server/tools/project/GetBuildLogsTool.js +2 -3
- package/mcp-server/tools/project/GetBuildStatusTool.js +2 -3
- package/mcp-server/tools/project/UploadProjectTools.js +3 -5
- package/package.json +3 -3
- package/types/Projects.d.ts +1 -5
- package/lib/jsonOutput.d.ts +0 -182
- package/lib/jsonOutput.js +0 -158
|
@@ -35,7 +35,14 @@ function validateSrcPath(src) {
|
|
|
35
35
|
async function determineSrcAndDest(args) {
|
|
36
36
|
let absoluteSrc;
|
|
37
37
|
let dest;
|
|
38
|
-
|
|
38
|
+
let projectDir;
|
|
39
|
+
let projectConfig;
|
|
40
|
+
try {
|
|
41
|
+
({ projectDir, projectConfig } = getProjectConfig());
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Not in a project (handled below)
|
|
45
|
+
}
|
|
39
46
|
if (!(projectDir && projectConfig)) {
|
|
40
47
|
// Not in a project, prompt for src and dest of traditional theme
|
|
41
48
|
const previewPromptAnswers = await previewPrompt(args);
|
package/commands/getStarted.js
CHANGED
|
@@ -7,7 +7,7 @@ import { commands } from '../lang/en.js';
|
|
|
7
7
|
import { GET_STARTED_OPTIONS, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, PROJECT_CONFIG_FILE, } from '../lib/constants.js';
|
|
8
8
|
import { EXIT_CODES } from '../lib/enums/exitCodes.js';
|
|
9
9
|
import { debugError, logError } from '../lib/errorHandlers/index.js';
|
|
10
|
-
import { getProjectConfig,
|
|
10
|
+
import { getProjectConfig, writeProjectConfig, ProjectConfigValidationError, } from '../lib/projects/config.js';
|
|
11
11
|
import { handleProjectUpload } from '../lib/projects/upload.js';
|
|
12
12
|
import { projectNameAndDestPrompt } from '../lib/prompts/projectNameAndDestPrompt.js';
|
|
13
13
|
import { promptUser } from '../lib/prompts/promptUtils.js';
|
|
@@ -20,7 +20,6 @@ import { pollProjectBuildAndDeploy } from '../lib/projects/pollProjectBuildAndDe
|
|
|
20
20
|
import { fetchPublicAppsForPortal } from '@hubspot/local-dev-lib/api/appsDev';
|
|
21
21
|
import { getConfigAccountEnvironment } from '@hubspot/local-dev-lib/config';
|
|
22
22
|
import { getStaticAuthAppInstallUrl } from '../lib/app/urls.js';
|
|
23
|
-
import ProjectValidationError from '../lib/errors/ProjectValidationError.js';
|
|
24
23
|
import { openLink } from '../lib/links.js';
|
|
25
24
|
import { runGetStartedV2 } from '../lib/getStarted/getStartedV2.js';
|
|
26
25
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
@@ -98,10 +97,14 @@ async function handler(args) {
|
|
|
98
97
|
uiLogger.log(commands.getStarted.logs.appSelected);
|
|
99
98
|
const { dest, name } = await projectNameAndDestPrompt(args);
|
|
100
99
|
const projectDest = path.resolve(getCwd(), dest);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
existingProjectDir
|
|
104
|
-
|
|
100
|
+
let existingProjectDir;
|
|
101
|
+
try {
|
|
102
|
+
existingProjectDir = getProjectConfig(projectDest).projectDir;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Not in a project directory
|
|
106
|
+
}
|
|
107
|
+
if (existingProjectDir && projectDest.startsWith(existingProjectDir)) {
|
|
105
108
|
// Track nested project error
|
|
106
109
|
await trackCommandMetadataUsage('get-started', {
|
|
107
110
|
successful: false,
|
|
@@ -167,29 +170,21 @@ async function handler(args) {
|
|
|
167
170
|
if (shouldUpload) {
|
|
168
171
|
try {
|
|
169
172
|
// Get the project config for the newly created project
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
// Track config file not found error
|
|
173
|
-
await trackCommandMetadataUsage('get-started', {
|
|
174
|
-
successful: false,
|
|
175
|
-
step: 'config-file-not-found',
|
|
176
|
-
}, derivedAccountId);
|
|
177
|
-
uiLogger.log(' ');
|
|
178
|
-
uiLogger.error(commands.getStarted.errors.configFileNotFound);
|
|
179
|
-
return exit(EXIT_CODES.ERROR);
|
|
180
|
-
}
|
|
173
|
+
let newProjectConfig;
|
|
174
|
+
let newProjectDir;
|
|
181
175
|
try {
|
|
182
|
-
|
|
176
|
+
({ projectConfig: newProjectConfig, projectDir: newProjectDir } =
|
|
177
|
+
getProjectConfig(projectDest));
|
|
183
178
|
}
|
|
184
179
|
catch (error) {
|
|
185
|
-
if (error instanceof
|
|
180
|
+
if (error instanceof ProjectConfigValidationError) {
|
|
186
181
|
// Track validation error
|
|
187
182
|
await trackCommandMetadataUsage('get-started', {
|
|
188
183
|
successful: false,
|
|
189
184
|
step: 'project-validation-failed',
|
|
190
185
|
}, derivedAccountId);
|
|
191
186
|
uiLogger.log(' ');
|
|
192
|
-
uiLogger.error(error.message);
|
|
187
|
+
uiLogger.error(error.message || commands.getStarted.errors.configFileNotFound);
|
|
193
188
|
return exit(EXIT_CODES.ERROR);
|
|
194
189
|
}
|
|
195
190
|
throw error;
|
package/commands/project/add.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { logError } from '../../lib/errorHandlers/index.js';
|
|
2
|
-
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
2
|
+
import { getIsInProject, getProjectConfig } from '../../lib/projects/config.js';
|
|
3
3
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
4
4
|
import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
|
|
5
5
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
@@ -14,12 +14,13 @@ const command = 'add';
|
|
|
14
14
|
const describe = commands.project.add.describe;
|
|
15
15
|
async function handler(args) {
|
|
16
16
|
const { derivedAccountId, exit } = args;
|
|
17
|
+
const isInProjectDir = getIsInProject();
|
|
18
|
+
if (!isInProjectDir) {
|
|
19
|
+
uiLogger.error(commands.project.add.error.locationInProject);
|
|
20
|
+
return exit(EXIT_CODES.ERROR);
|
|
21
|
+
}
|
|
17
22
|
try {
|
|
18
|
-
const { projectConfig, projectDir } =
|
|
19
|
-
if (!projectDir || !projectConfig) {
|
|
20
|
-
uiLogger.error(commands.project.add.error.locationInProject);
|
|
21
|
-
return exit(EXIT_CODES.ERROR);
|
|
22
|
-
}
|
|
23
|
+
const { projectConfig, projectDir } = getProjectConfig();
|
|
23
24
|
const isLegacyProjectCreate = isLegacyProject(projectConfig.platformVersion);
|
|
24
25
|
if (!isLegacyProjectCreate) {
|
|
25
26
|
await v2AddComponent(args, projectDir, projectConfig, derivedAccountId);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
import { InstallStatusJsonOutput } from '../../lib/jsonOutput.js';
|
|
2
|
+
import { InstallStatusJsonOutput } from '../../lib/jsonOutput/appInstallStatus.js';
|
|
3
3
|
export type ProjectInstallStatusArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<InstallStatusJsonOutput>;
|
|
4
4
|
declare const projectInstallStatusCommand: YargsCommandModule<unknown, ProjectInstallStatusArgs>;
|
|
5
5
|
export default projectInstallStatusCommand;
|
|
@@ -5,7 +5,7 @@ import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
|
5
5
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
6
6
|
import { translateForLocalDev } from '@hubspot/project-parsing-lib/translate';
|
|
7
7
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
8
|
-
import { InstallStatusSchema, } from '../../lib/jsonOutput.js';
|
|
8
|
+
import { InstallStatusSchema, } from '../../lib/jsonOutput/appInstallStatus.js';
|
|
9
9
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
10
10
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
11
11
|
import { ApiErrorContext, debugError, logError, } from '../../lib/errorHandlers/index.js';
|
|
@@ -18,9 +18,13 @@ const command = 'app-install-status';
|
|
|
18
18
|
const describe = commands.project.installStatus.describe;
|
|
19
19
|
async function handler(args) {
|
|
20
20
|
const { derivedAccountId, formatOutputAsJson, exit, addJsonOutput } = args;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
let projectConfig;
|
|
22
|
+
let projectDir;
|
|
23
|
+
try {
|
|
24
|
+
({ projectConfig, projectDir } = getProjectConfig());
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
logError(error);
|
|
24
28
|
return exit(EXIT_CODES.ERROR);
|
|
25
29
|
}
|
|
26
30
|
if (isLegacyProject(projectConfig.platformVersion)) {
|
|
@@ -15,6 +15,7 @@ import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
|
15
15
|
import { commands } from '../../lang/en.js';
|
|
16
16
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
17
17
|
import { handleProjectCreationFlow, } from '../../lib/projects/create/index.js';
|
|
18
|
+
import { getProjectCreateFailureReason } from '../../lib/projects/create/tracking.js';
|
|
18
19
|
import { updateHsMetaFilesWithAutoGeneratedFields } from '../../lib/projects/components.js';
|
|
19
20
|
import SpinniesManager from '../../lib/ui/SpinniesManager.js';
|
|
20
21
|
import { showMcpPromotionNudge } from '../../lib/mcp/promotion.js';
|
|
@@ -24,6 +25,10 @@ const BETA_VERSIONS = [
|
|
|
24
25
|
PLATFORM_VERSIONS.v2026_09_BETA,
|
|
25
26
|
PLATFORM_VERSIONS.v2026_03_BETA,
|
|
26
27
|
];
|
|
28
|
+
const TRACKING_STEP = {
|
|
29
|
+
CREATION_FLOW: 'project-creation-flow',
|
|
30
|
+
DOWNLOAD: 'download-project',
|
|
31
|
+
};
|
|
27
32
|
async function handler(args) {
|
|
28
33
|
const { platformVersion, templateSource, exit, addUsageMetadata } = args;
|
|
29
34
|
if (BETA_VERSIONS.includes(platformVersion)) {
|
|
@@ -39,6 +44,9 @@ async function handler(args) {
|
|
|
39
44
|
handleResult = await handleProjectCreationFlow(args);
|
|
40
45
|
}
|
|
41
46
|
catch (error) {
|
|
47
|
+
addUsageMetadata({
|
|
48
|
+
step: `${TRACKING_STEP.CREATION_FLOW}:${getProjectCreateFailureReason(error)}`,
|
|
49
|
+
});
|
|
42
50
|
logError(error);
|
|
43
51
|
return exit(EXIT_CODES.ERROR);
|
|
44
52
|
}
|
|
@@ -51,13 +59,16 @@ async function handler(args) {
|
|
|
51
59
|
.join(','),
|
|
52
60
|
});
|
|
53
61
|
const projectDest = path.resolve(getCwd(), projectNameAndDestPromptResponse.dest);
|
|
54
|
-
const { projectConfig: existingProjectConfig, projectDir: existingProjectDir, } = await getProjectConfig(projectDest);
|
|
55
62
|
// Exit if the target destination is within an existing project
|
|
56
|
-
|
|
57
|
-
existingProjectDir
|
|
58
|
-
projectDest.startsWith(existingProjectDir)) {
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
try {
|
|
64
|
+
const { projectDir: existingProjectDir } = getProjectConfig(projectDest);
|
|
65
|
+
if (projectDest.startsWith(existingProjectDir)) {
|
|
66
|
+
uiLogger.error(commands.project.create.errors.cannotNestProjects(existingProjectDir));
|
|
67
|
+
return exit(EXIT_CODES.ERROR);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Not in a project directory, which is the expected case for create
|
|
61
72
|
}
|
|
62
73
|
const components = generateComponentPaths({
|
|
63
74
|
selectProjectTemplatePromptResponse,
|
|
@@ -80,6 +91,9 @@ async function handler(args) {
|
|
|
80
91
|
});
|
|
81
92
|
}
|
|
82
93
|
catch (err) {
|
|
94
|
+
addUsageMetadata({
|
|
95
|
+
step: `${TRACKING_STEP.DOWNLOAD}:${getProjectCreateFailureReason(err)}`,
|
|
96
|
+
});
|
|
83
97
|
SpinniesManager.fail('project-create', {
|
|
84
98
|
text: commands.project.create.failure(isProjectEmpty, projectNameAndDestPromptResponse.name),
|
|
85
99
|
});
|
|
@@ -23,7 +23,7 @@ async function handler(args) {
|
|
|
23
23
|
if (!force) {
|
|
24
24
|
await confirmDeletion(projectName, derivedAccountId, projectId);
|
|
25
25
|
}
|
|
26
|
-
if (!isLegacyProject(platformVersion)
|
|
26
|
+
if (hasUnifiedComponents && !isLegacyProject(platformVersion)) {
|
|
27
27
|
await deleteDeployedComponents(derivedAccountId, projectName);
|
|
28
28
|
}
|
|
29
29
|
await handleProjectDeletion(derivedAccountId, projectName);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
import { DeployJsonOutput } from '../../lib/jsonOutput.js';
|
|
2
|
+
import { DeployJsonOutput } from '../../lib/jsonOutput/deploy.js';
|
|
3
3
|
export type ProjectDeployArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<DeployJsonOutput> & {
|
|
4
4
|
project?: string;
|
|
5
5
|
build?: number;
|
|
@@ -3,14 +3,14 @@ import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
|
|
|
3
3
|
import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
|
|
4
4
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
5
5
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
6
|
-
import { getProjectConfig
|
|
6
|
+
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
7
7
|
import { projectNamePrompt } from '../../lib/prompts/projectNamePrompt.js';
|
|
8
8
|
import { projectProfilePrompt } from '../../lib/prompts/projectProfilePrompt.js';
|
|
9
9
|
import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
10
10
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
11
11
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
12
12
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
13
|
-
import { DeploySchema } from '../../lib/jsonOutput.js';
|
|
13
|
+
import { DeploySchema } from '../../lib/jsonOutput/deploy.js';
|
|
14
14
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
15
15
|
import { loadProfile } from '../../lib/projects/projectProfiles.js';
|
|
16
16
|
import { PROJECT_DEPLOY_TEXT } from '../../lib/constants.js';
|
|
@@ -25,22 +25,24 @@ async function handler(args) {
|
|
|
25
25
|
const accountConfig = getConfigAccountById(derivedAccountId);
|
|
26
26
|
const accountType = accountConfig && accountConfig.accountType;
|
|
27
27
|
let targetAccountId;
|
|
28
|
-
|
|
28
|
+
let loadedConfig;
|
|
29
29
|
let isInProjectDirectory = false;
|
|
30
|
-
// Validate project config, but it's valid to run this command from outside a project dir
|
|
31
30
|
try {
|
|
32
|
-
|
|
31
|
+
loadedConfig = getProjectConfig();
|
|
33
32
|
isInProjectDirectory = true;
|
|
34
33
|
}
|
|
35
|
-
catch (e) {
|
|
34
|
+
catch (e) {
|
|
35
|
+
// Do nothing, it's valid to run this command from outside a project dir
|
|
36
|
+
}
|
|
36
37
|
if (isInProjectDirectory &&
|
|
37
|
-
|
|
38
|
+
loadedConfig &&
|
|
39
|
+
!isLegacyProject(loadedConfig.projectConfig.platformVersion)) {
|
|
38
40
|
try {
|
|
39
|
-
const profileName = await projectProfilePrompt(projectDir, projectConfig, profileOption, !!useEnvOption);
|
|
41
|
+
const profileName = await projectProfilePrompt(loadedConfig.projectDir, loadedConfig.projectConfig, profileOption, !!useEnvOption);
|
|
40
42
|
if (profileName) {
|
|
41
43
|
// Use loadProfile instead of loadAndValidateProfile because the local
|
|
42
44
|
// profile does not need to be valid to successfully deploy
|
|
43
|
-
const profile = loadProfile(projectConfig, projectDir, profileName);
|
|
45
|
+
const profile = loadProfile(loadedConfig.projectConfig, loadedConfig.projectDir, profileName);
|
|
44
46
|
targetAccountId = profile.accountId;
|
|
45
47
|
uiLogger.log(commands.project.deploy.profileMessage(profileName, targetAccountId));
|
|
46
48
|
uiLogger.log('');
|
|
@@ -58,8 +60,8 @@ async function handler(args) {
|
|
|
58
60
|
addUsageMetadata({ type: accountType });
|
|
59
61
|
}
|
|
60
62
|
let projectName = projectOption;
|
|
61
|
-
if (!projectOption &&
|
|
62
|
-
projectName = projectConfig.name;
|
|
63
|
+
if (!projectOption && loadedConfig) {
|
|
64
|
+
projectName = loadedConfig.projectConfig.name;
|
|
63
65
|
}
|
|
64
66
|
const namePromptResponse = await projectNamePrompt(targetAccountId, {
|
|
65
67
|
project: projectName,
|
|
@@ -116,7 +118,7 @@ async function handler(args) {
|
|
|
116
118
|
catch {
|
|
117
119
|
return exit(EXIT_CODES.ERROR);
|
|
118
120
|
}
|
|
119
|
-
const deployResult = await handleProjectDeploy(targetAccountId, projectName, buildIdToDeploy, isLegacyProject(projectConfig
|
|
121
|
+
const deployResult = await handleProjectDeploy(targetAccountId, projectName, buildIdToDeploy, isLegacyProject(loadedConfig?.projectConfig.platformVersion), forceOption);
|
|
120
122
|
if (!deployResult) {
|
|
121
123
|
return exit(EXIT_CODES.ERROR);
|
|
122
124
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getConfigAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
2
|
-
import { getProjectConfig
|
|
2
|
+
import { getProjectConfig } from '../../../lib/projects/config.js';
|
|
3
3
|
import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
|
|
4
4
|
import { uiLine } from '../../../lib/ui/index.js';
|
|
5
5
|
import { makeWrappedYargsHandler } from '../../../lib/yargs/makeWrappedYargsHandler.js';
|
|
@@ -17,18 +17,15 @@ const command = 'dev';
|
|
|
17
17
|
const describe = commands.project.dev.describe;
|
|
18
18
|
async function handler(args) {
|
|
19
19
|
const { derivedAccountId, testingAccount, projectAccount, profile: profileOption, exit, addUsageMetadata, } = args;
|
|
20
|
-
|
|
20
|
+
let projectConfig;
|
|
21
|
+
let projectDir;
|
|
21
22
|
try {
|
|
22
|
-
|
|
23
|
+
({ projectConfig, projectDir } = getProjectConfig());
|
|
23
24
|
}
|
|
24
25
|
catch (error) {
|
|
25
26
|
logError(error);
|
|
26
27
|
return exit(EXIT_CODES.ERROR);
|
|
27
28
|
}
|
|
28
|
-
if (!projectDir) {
|
|
29
|
-
uiLogger.error(commands.project.dev.errors.noProjectConfig);
|
|
30
|
-
return exit(EXIT_CODES.ERROR);
|
|
31
|
-
}
|
|
32
29
|
if (isLegacyProject(projectConfig.platformVersion)) {
|
|
33
30
|
uiLogger.error(commands.project.dev.errors.unsupportedPlatformVersion(projectConfig.platformVersion));
|
|
34
31
|
return exit(EXIT_CODES.ERROR);
|
|
@@ -4,7 +4,7 @@ import { extractZipArchive } from '@hubspot/local-dev-lib/archive';
|
|
|
4
4
|
import { downloadProject, fetchProjectBuilds, } from '@hubspot/local-dev-lib/api/projects';
|
|
5
5
|
import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
|
|
6
6
|
import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
|
|
7
|
-
import {
|
|
7
|
+
import { getIsInProject } from '../../lib/projects/config.js';
|
|
8
8
|
import { downloadProjectPrompt } from '../../lib/prompts/downloadProjectPrompt.js';
|
|
9
9
|
import { commands } from '../../lang/en.js';
|
|
10
10
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
@@ -15,8 +15,8 @@ const command = 'download';
|
|
|
15
15
|
const describe = commands.project.download.describe;
|
|
16
16
|
async function handler(args) {
|
|
17
17
|
const { dest, build, derivedAccountId, exit } = args;
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
18
|
+
const isInProjectDir = getIsInProject();
|
|
19
|
+
if (isInProjectDir) {
|
|
20
20
|
uiLogger.error(commands.project.download.warnings.cannotDownloadWithinProject);
|
|
21
21
|
return exit(EXIT_CODES.ERROR);
|
|
22
22
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
import { ProjectInfoJsonOutput } from '../../lib/jsonOutput.js';
|
|
2
|
+
import { ProjectInfoJsonOutput } from '../../lib/jsonOutput/info.js';
|
|
3
3
|
export type ProjectInfoArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ProjectInfoJsonOutput>;
|
|
4
4
|
declare const projectInfoCommand: YargsCommandModule<unknown, ProjectInfoArgs>;
|
|
5
5
|
export default projectInfoCommand;
|
package/commands/project/info.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
2
2
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
3
3
|
import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
|
|
4
|
-
import { debugError } from '../../lib/errorHandlers/index.js';
|
|
4
|
+
import { debugError, logError } from '../../lib/errorHandlers/index.js';
|
|
5
5
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
6
6
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
7
7
|
import { commands } from '../../lang/en.js';
|
|
8
8
|
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
9
9
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
10
10
|
import { getProjectInfo, logProjectInfo, } from '../../lib/projects/projectInfo.js';
|
|
11
|
-
import { ProjectInfoSchema, } from '../../lib/jsonOutput.js';
|
|
11
|
+
import { ProjectInfoSchema, } from '../../lib/jsonOutput/info.js';
|
|
12
12
|
const command = 'info';
|
|
13
13
|
const describe = commands.project.info.describe;
|
|
14
14
|
const verboseDescribe = commands.project.info.verboseDescribe;
|
|
15
15
|
async function handler(args) {
|
|
16
16
|
const { derivedAccountId, formatOutputAsJson, exit, addJsonOutput } = args;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
let projectConfig;
|
|
18
|
+
try {
|
|
19
|
+
({ projectConfig } = getProjectConfig());
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
logError(error);
|
|
20
23
|
return exit(EXIT_CODES.ERROR);
|
|
21
24
|
}
|
|
22
25
|
if (isLegacyProject(projectConfig.platformVersion)) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
import { InstallAppJsonOutput } from '../../lib/jsonOutput.js';
|
|
2
|
+
import { InstallAppJsonOutput } from '../../lib/jsonOutput/installApp.js';
|
|
3
3
|
export type ProjectInstallAppArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<InstallAppJsonOutput> & {
|
|
4
4
|
force: boolean;
|
|
5
5
|
profile?: string;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { getConfigAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
3
3
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
4
|
-
import { InstallAppSchema, } from '../../lib/jsonOutput.js';
|
|
4
|
+
import { InstallAppSchema, } from '../../lib/jsonOutput/installApp.js';
|
|
5
5
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
6
6
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
7
|
+
import { logError } from '../../lib/errorHandlers/index.js';
|
|
7
8
|
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
8
9
|
import { commands } from '../../lang/en.js';
|
|
9
10
|
import { getProjectConfig } from '../../lib/projects/config.js';
|
|
@@ -15,9 +16,13 @@ const describe = commands.project.installApp.describe;
|
|
|
15
16
|
const verboseDescribe = commands.project.installApp.verboseDescribe;
|
|
16
17
|
async function handler(args) {
|
|
17
18
|
const { derivedAccountId, formatOutputAsJson, force, profile: profileOption, useEnv: useEnvOption, exit, addJsonOutput, } = args;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
let projectConfig;
|
|
20
|
+
let projectDir;
|
|
21
|
+
try {
|
|
22
|
+
({ projectConfig, projectDir } = getProjectConfig());
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
logError(error);
|
|
21
26
|
return exit(EXIT_CODES.ERROR);
|
|
22
27
|
}
|
|
23
28
|
if (isLegacyProject(projectConfig.platformVersion)) {
|
|
@@ -5,7 +5,6 @@ import { getProjectConfig } from '../../lib/projects/config.js';
|
|
|
5
5
|
import { promptUser } from '../../lib/prompts/promptUtils.js';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { commands } from '../../lang/en.js';
|
|
8
|
-
import { uiLogger } from '../../lib/ui/logger.js';
|
|
9
8
|
import { makeWrappedYargsHandler } from '../../lib/yargs/makeWrappedYargsHandler.js';
|
|
10
9
|
import { logError } from '../../lib/errorHandlers/index.js';
|
|
11
10
|
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
@@ -15,12 +14,14 @@ const describe = commands.project.installDeps.help.describe;
|
|
|
15
14
|
async function handler(args) {
|
|
16
15
|
const { packages, exit } = args;
|
|
17
16
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
let projectDir;
|
|
18
|
+
try {
|
|
19
|
+
({ projectDir } = getProjectConfig());
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
logError(error);
|
|
21
23
|
return exit(EXIT_CODES.ERROR);
|
|
22
24
|
}
|
|
23
|
-
const { projectDir } = projectConfig;
|
|
24
25
|
let installLocations = await getProjectPackageJsonLocations();
|
|
25
26
|
if (packages) {
|
|
26
27
|
const { selectedInstallLocations } = await promptUser([
|
package/commands/project/lint.js
CHANGED
|
@@ -17,16 +17,23 @@ const describe = commands.project.lint.help.describe;
|
|
|
17
17
|
async function handler(args) {
|
|
18
18
|
const { installMissingDeps, exit } = args;
|
|
19
19
|
try {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
let projectConfig;
|
|
21
|
+
let projectDir;
|
|
22
|
+
try {
|
|
23
|
+
({ projectConfig, projectDir } = getProjectConfig());
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
logError(error);
|
|
23
27
|
return exit(EXIT_CODES.ERROR);
|
|
24
28
|
}
|
|
25
29
|
SpinniesManager.init({ succeedColor: 'white' });
|
|
26
30
|
SpinniesManager.add('lintCheck', {
|
|
27
31
|
text: commands.project.lint.loading.checking,
|
|
28
32
|
});
|
|
29
|
-
const lintLocations = await getUieLintablePackageJsonLocations(
|
|
33
|
+
const lintLocations = await getUieLintablePackageJsonLocations({
|
|
34
|
+
projectConfig,
|
|
35
|
+
projectDir,
|
|
36
|
+
});
|
|
30
37
|
const locationsReadyToLint = [];
|
|
31
38
|
const locationsNeedingPackages = new Map();
|
|
32
39
|
let skippedDirectoryCount = 0;
|
|
@@ -44,7 +51,7 @@ async function handler(args) {
|
|
|
44
51
|
SpinniesManager.succeed('lintCheck');
|
|
45
52
|
if (locationsNeedingPackages.size > 0) {
|
|
46
53
|
const locationsArray = Array.from(locationsNeedingPackages.keys());
|
|
47
|
-
const relativeLocations = locationsArray.map(loc => path.relative(
|
|
54
|
+
const relativeLocations = locationsArray.map(loc => path.relative(projectDir, loc));
|
|
48
55
|
const allMissingPackages = [];
|
|
49
56
|
for (const packages of locationsNeedingPackages.values()) {
|
|
50
57
|
allMissingPackages.push(...packages);
|
|
@@ -94,7 +101,7 @@ async function handler(args) {
|
|
|
94
101
|
const hasModernConfig = hasEslintConfig(location);
|
|
95
102
|
const hasDeprecatedConfig = hasDeprecatedEslintConfig(location);
|
|
96
103
|
if (hasDeprecatedConfig) {
|
|
97
|
-
const relativePath = path.relative(
|
|
104
|
+
const relativePath = path.relative(projectDir, location);
|
|
98
105
|
const deprecatedFiles = getDeprecatedEslintConfigFiles(location);
|
|
99
106
|
deprecatedConfigDetails.push({
|
|
100
107
|
path: relativePath,
|
|
@@ -110,7 +117,7 @@ async function handler(args) {
|
|
|
110
117
|
uiLogger.warn(commands.project.lint.deprecatedEslintConfigWarning(deprecatedConfigDetails));
|
|
111
118
|
}
|
|
112
119
|
if (locationsNeedingConfig.length > 0) {
|
|
113
|
-
const relativeLocations = locationsNeedingConfig.map(loc => path.relative(
|
|
120
|
+
const relativeLocations = locationsNeedingConfig.map(loc => path.relative(projectDir, loc));
|
|
114
121
|
const { shouldCreateConfig } = await promptUser([
|
|
115
122
|
{
|
|
116
123
|
name: 'shouldCreateConfig',
|
|
@@ -123,7 +130,7 @@ async function handler(args) {
|
|
|
123
130
|
SpinniesManager.add('lintConfigCreate', {
|
|
124
131
|
text: commands.project.lint.loading.creatingConfig,
|
|
125
132
|
});
|
|
126
|
-
const platformVersion = projectConfig.
|
|
133
|
+
const platformVersion = projectConfig.platformVersion ?? null;
|
|
127
134
|
const createdConfigs = [];
|
|
128
135
|
for (const location of locationsNeedingConfig) {
|
|
129
136
|
const configPath = await createEslintConfig(location, platformVersion);
|
|
@@ -159,7 +166,7 @@ async function handler(args) {
|
|
|
159
166
|
SpinniesManager.add('lintRun', {
|
|
160
167
|
text: commands.project.lint.loading.linting,
|
|
161
168
|
});
|
|
162
|
-
const { success, results } = await lintPackages(locationsReadyToLint,
|
|
169
|
+
const { success, results } = await lintPackages(locationsReadyToLint, projectDir);
|
|
163
170
|
SpinniesManager.succeed('lintRun');
|
|
164
171
|
displayLintResults(results);
|
|
165
172
|
if (!success) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
|
|
1
|
+
import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
import { ProjectListJsonOutput } from '../../lib/jsonOutput/projectList.js';
|
|
3
|
+
export type ProjectListArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ProjectListJsonOutput>;
|
|
3
4
|
declare const projectListCommand: YargsCommandModule<unknown, ProjectListArgs>;
|
|
4
5
|
export default projectListCommand;
|
package/commands/project/list.js
CHANGED
|
@@ -6,6 +6,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
|
6
6
|
import { uiLogger } from '../../lib/ui/logger.js';
|
|
7
7
|
import { commands } from '../../lang/en.js';
|
|
8
8
|
import { renderTable } from '../../ui/render.js';
|
|
9
|
+
import { ProjectListSchema, mapProjectToListItem, } from '../../lib/jsonOutput/projectList.js';
|
|
9
10
|
const command = ['list', 'ls'];
|
|
10
11
|
const describe = commands.project.list.describe;
|
|
11
12
|
async function getProjectData(accountId) {
|
|
@@ -23,7 +24,7 @@ function formatProjectsAsTableRows(projects) {
|
|
|
23
24
|
return projectListData;
|
|
24
25
|
}
|
|
25
26
|
async function handler(args) {
|
|
26
|
-
const { derivedAccountId, exit } = args;
|
|
27
|
+
const { derivedAccountId, formatOutputAsJson, exit, addJsonOutput } = args;
|
|
27
28
|
let projectData;
|
|
28
29
|
try {
|
|
29
30
|
projectData = await getProjectData(derivedAccountId);
|
|
@@ -33,9 +34,20 @@ async function handler(args) {
|
|
|
33
34
|
return exit(EXIT_CODES.ERROR);
|
|
34
35
|
}
|
|
35
36
|
if (projectData.length === 0) {
|
|
37
|
+
if (formatOutputAsJson) {
|
|
38
|
+
addJsonOutput({ accountId: derivedAccountId, results: [] });
|
|
39
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
40
|
+
}
|
|
36
41
|
uiLogger.error(commands.project.list.errors.noProjectsFound(derivedAccountId));
|
|
37
42
|
return exit(EXIT_CODES.ERROR);
|
|
38
43
|
}
|
|
44
|
+
if (formatOutputAsJson) {
|
|
45
|
+
addJsonOutput({
|
|
46
|
+
accountId: derivedAccountId,
|
|
47
|
+
results: projectData.map(mapProjectToListItem),
|
|
48
|
+
});
|
|
49
|
+
return exit(EXIT_CODES.SUCCESS);
|
|
50
|
+
}
|
|
39
51
|
const projectListData = formatProjectsAsTableRows(projectData);
|
|
40
52
|
const tableHeader = [
|
|
41
53
|
commands.project.list.labels.name,
|
|
@@ -45,7 +57,10 @@ async function handler(args) {
|
|
|
45
57
|
renderTable(tableHeader, projectListData);
|
|
46
58
|
}
|
|
47
59
|
function projectListBuilder(yargs) {
|
|
48
|
-
yargs.example([
|
|
60
|
+
yargs.example([
|
|
61
|
+
['$0 project list', commands.project.list.examples.default],
|
|
62
|
+
['$0 project list --json', commands.project.list.examples.json],
|
|
63
|
+
]);
|
|
49
64
|
return yargs;
|
|
50
65
|
}
|
|
51
66
|
const builder = makeYargsBuilder(projectListBuilder, command, describe, {
|
|
@@ -53,11 +68,14 @@ const builder = makeYargsBuilder(projectListBuilder, command, describe, {
|
|
|
53
68
|
useConfigOptions: true,
|
|
54
69
|
useAccountOptions: true,
|
|
55
70
|
useEnvironmentOptions: true,
|
|
71
|
+
useJSONOutputOptions: true,
|
|
56
72
|
});
|
|
57
73
|
const projectListCommand = {
|
|
58
74
|
command,
|
|
59
75
|
describe,
|
|
60
|
-
handler: makeWrappedYargsHandler('project-list', handler
|
|
76
|
+
handler: makeWrappedYargsHandler('project-list', handler, {
|
|
77
|
+
jsonOutputSchema: ProjectListSchema,
|
|
78
|
+
}),
|
|
61
79
|
builder,
|
|
62
80
|
};
|
|
63
81
|
export default projectListCommand;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
import { ProjectBuildsListJsonOutput } from '../../lib/jsonOutput.js';
|
|
2
|
+
import { ProjectBuildsListJsonOutput } from '../../lib/jsonOutput/listBuilds.js';
|
|
3
3
|
export type ProjectListBuildsArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs<ProjectBuildsListJsonOutput> & {
|
|
4
4
|
project?: string;
|
|
5
5
|
limit?: number;
|