@hubspot/cli 8.14.0 → 8.15.0-beta.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/commands/cms/theme/preview.js +8 -1
- package/commands/getStarted.js +16 -21
- 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 +24 -7
- 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.d.ts +3 -2
- package/commands/project/download.js +18 -5
- 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 -19
- 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.d.ts +3 -2
- package/commands/project/validate.js +67 -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 +9 -19
- package/lang/en.js +9 -19
- package/lib/app/migrate.js +5 -7
- package/lib/constants.d.ts +0 -1
- package/lib/constants.js +0 -1
- 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/filesystem.d.ts +6 -0
- package/lib/filesystem.js +9 -0
- 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/download.d.ts +7 -0
- package/lib/jsonOutput/download.js +6 -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/jsonOutput/validate.d.ts +36 -0
- package/lib/jsonOutput/validate.js +20 -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 +3 -2
- package/lib/projects/projectProfiles.js +8 -3
- package/lib/projects/release.js +1 -1
- package/lib/projects/uieLinting.d.ts +2 -0
- package/lib/projects/uieLinting.js +13 -11
- package/lib/projects/upload.d.ts +5 -1
- package/lib/projects/upload.js +6 -1
- package/lib/projects/validate.d.ts +18 -0
- package/lib/projects/validate.js +142 -0
- package/lib/projects/validateLintConfigOnUpload.js +6 -5
- package/lib/projects/workspaces.js +6 -13
- package/lib/theme/migrate.js +1 -4
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +1 -1
- package/mcp-server/tools/project/CreateProjectTool.d.ts +1 -1
- 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/mcp-server/tools/project/constants.d.ts +1 -1
- 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
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Release } from '../../api/releases.js';
|
|
3
|
+
declare const ReleaseComponentSchema: z.ZodObject<{
|
|
4
|
+
buildType: z.ZodString;
|
|
5
|
+
buildName: z.ZodOptional<z.ZodString>;
|
|
6
|
+
rootPath: z.ZodOptional<z.ZodString>;
|
|
7
|
+
id: z.ZodOptional<z.ZodString>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export declare const ReleaseSchema: z.ZodObject<{
|
|
10
|
+
releaseTag: z.ZodString;
|
|
11
|
+
buildId: z.ZodNumber;
|
|
12
|
+
createdAt: z.ZodString;
|
|
13
|
+
components: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
14
|
+
buildType: z.ZodString;
|
|
15
|
+
buildName: z.ZodOptional<z.ZodString>;
|
|
16
|
+
rootPath: z.ZodOptional<z.ZodString>;
|
|
17
|
+
id: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>>>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export declare const ReleaseListSchema: z.ZodObject<{
|
|
21
|
+
results: z.ZodArray<z.ZodObject<{
|
|
22
|
+
releaseTag: z.ZodString;
|
|
23
|
+
buildId: z.ZodNumber;
|
|
24
|
+
createdAt: z.ZodString;
|
|
25
|
+
components: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
26
|
+
buildType: z.ZodString;
|
|
27
|
+
buildName: z.ZodOptional<z.ZodString>;
|
|
28
|
+
rootPath: z.ZodOptional<z.ZodString>;
|
|
29
|
+
id: z.ZodOptional<z.ZodString>;
|
|
30
|
+
}, z.core.$strip>>>;
|
|
31
|
+
}, z.core.$strip>>;
|
|
32
|
+
paging: z.ZodOptional<z.ZodObject<{
|
|
33
|
+
next: z.ZodObject<{
|
|
34
|
+
after: z.ZodString;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
}, z.core.$strip>>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
export type ReleaseComponentJsonOutput = z.infer<typeof ReleaseComponentSchema>;
|
|
39
|
+
export type ReleaseJsonOutput = z.infer<typeof ReleaseSchema>;
|
|
40
|
+
export type ReleaseListJsonOutput = z.infer<typeof ReleaseListSchema>;
|
|
41
|
+
export declare function mapReleaseToJsonOutput(release: Release): ReleaseJsonOutput;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const ReleaseComponentSchema = z.object({
|
|
3
|
+
buildType: z.string(),
|
|
4
|
+
buildName: z.string().optional(),
|
|
5
|
+
rootPath: z.string().optional(),
|
|
6
|
+
id: z.string().optional(),
|
|
7
|
+
});
|
|
8
|
+
export const ReleaseSchema = z.object({
|
|
9
|
+
releaseTag: z.string(),
|
|
10
|
+
buildId: z.number(),
|
|
11
|
+
createdAt: z.string(),
|
|
12
|
+
components: z.array(ReleaseComponentSchema).optional(),
|
|
13
|
+
});
|
|
14
|
+
export const ReleaseListSchema = z.object({
|
|
15
|
+
results: z.array(ReleaseSchema),
|
|
16
|
+
paging: z
|
|
17
|
+
.object({
|
|
18
|
+
next: z.object({
|
|
19
|
+
after: z.string(),
|
|
20
|
+
}),
|
|
21
|
+
})
|
|
22
|
+
.optional(),
|
|
23
|
+
});
|
|
24
|
+
export function mapReleaseToJsonOutput(release) {
|
|
25
|
+
const { releaseTag, buildId, createdAt, components } = release;
|
|
26
|
+
return {
|
|
27
|
+
releaseTag,
|
|
28
|
+
buildId,
|
|
29
|
+
createdAt,
|
|
30
|
+
components: components?.map(({ buildType, buildName, rootPath, id }) => ({
|
|
31
|
+
buildType,
|
|
32
|
+
buildName,
|
|
33
|
+
rootPath,
|
|
34
|
+
id,
|
|
35
|
+
})),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { HubSpotConfigAccount } from '@hubspot/local-dev-lib/types/Accounts';
|
|
3
|
+
declare const PreviewSchema: z.ZodObject<{
|
|
4
|
+
releaseTag: z.ZodOptional<z.ZodString>;
|
|
5
|
+
succeeded: z.ZodBoolean;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
declare const TargetAccountSchema: z.ZodObject<{
|
|
8
|
+
accountId: z.ZodNumber;
|
|
9
|
+
accountName: z.ZodOptional<z.ZodString>;
|
|
10
|
+
accountType: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export declare const UploadSchema: z.ZodObject<{
|
|
13
|
+
targetAccount: z.ZodOptional<z.ZodObject<{
|
|
14
|
+
accountId: z.ZodNumber;
|
|
15
|
+
accountName: z.ZodOptional<z.ZodString>;
|
|
16
|
+
accountType: z.ZodOptional<z.ZodString>;
|
|
17
|
+
}, z.core.$strip>>;
|
|
18
|
+
buildId: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
deployId: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
preview: z.ZodOptional<z.ZodObject<{
|
|
21
|
+
releaseTag: z.ZodOptional<z.ZodString>;
|
|
22
|
+
succeeded: z.ZodBoolean;
|
|
23
|
+
}, z.core.$strip>>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
export type PreviewJsonOutput = z.infer<typeof PreviewSchema>;
|
|
26
|
+
export type TargetAccountJsonOutput = z.infer<typeof TargetAccountSchema>;
|
|
27
|
+
export type UploadJsonOutput = z.infer<typeof UploadSchema>;
|
|
28
|
+
export declare function mapAccountToTargetAccount(accountId: number, account?: HubSpotConfigAccount | null): TargetAccountJsonOutput;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const PreviewSchema = z.object({
|
|
3
|
+
releaseTag: z.string().optional(),
|
|
4
|
+
succeeded: z.boolean(),
|
|
5
|
+
});
|
|
6
|
+
const TargetAccountSchema = z.object({
|
|
7
|
+
accountId: z.number(),
|
|
8
|
+
accountName: z.string().optional(),
|
|
9
|
+
accountType: z.string().optional(),
|
|
10
|
+
});
|
|
11
|
+
export const UploadSchema = z.object({
|
|
12
|
+
targetAccount: TargetAccountSchema.optional(),
|
|
13
|
+
buildId: z.number().optional(),
|
|
14
|
+
deployId: z.number().optional(),
|
|
15
|
+
preview: PreviewSchema.optional(),
|
|
16
|
+
});
|
|
17
|
+
export function mapAccountToTargetAccount(accountId, account) {
|
|
18
|
+
return {
|
|
19
|
+
accountId,
|
|
20
|
+
accountName: account?.name,
|
|
21
|
+
accountType: account?.accountType,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
declare const ValidationIssueSchema: z.ZodObject<{
|
|
3
|
+
message: z.ZodString;
|
|
4
|
+
file: z.ZodOptional<z.ZodString>;
|
|
5
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
declare const ProfileValidationSchema: z.ZodObject<{
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
accountId: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
valid: z.ZodBoolean;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export declare const ValidateSchema: z.ZodObject<{
|
|
13
|
+
valid: z.ZodBoolean;
|
|
14
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
15
|
+
platformVersion: z.ZodOptional<z.ZodString>;
|
|
16
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
17
|
+
errors: z.ZodArray<z.ZodObject<{
|
|
18
|
+
message: z.ZodString;
|
|
19
|
+
file: z.ZodOptional<z.ZodString>;
|
|
20
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>>;
|
|
22
|
+
warnings: z.ZodArray<z.ZodObject<{
|
|
23
|
+
message: z.ZodString;
|
|
24
|
+
file: z.ZodOptional<z.ZodString>;
|
|
25
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
26
|
+
}, z.core.$strip>>;
|
|
27
|
+
profiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
28
|
+
name: z.ZodString;
|
|
29
|
+
accountId: z.ZodOptional<z.ZodNumber>;
|
|
30
|
+
valid: z.ZodBoolean;
|
|
31
|
+
}, z.core.$strip>>>;
|
|
32
|
+
}, z.core.$strip>;
|
|
33
|
+
export type ValidationIssueJsonOutput = z.infer<typeof ValidationIssueSchema>;
|
|
34
|
+
export type ProfileValidationJsonOutput = z.infer<typeof ProfileValidationSchema>;
|
|
35
|
+
export type ValidateJsonOutput = z.infer<typeof ValidateSchema>;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const ValidationIssueSchema = z.object({
|
|
3
|
+
message: z.string(),
|
|
4
|
+
file: z.string().optional(),
|
|
5
|
+
profile: z.string().optional(),
|
|
6
|
+
});
|
|
7
|
+
const ProfileValidationSchema = z.object({
|
|
8
|
+
name: z.string(),
|
|
9
|
+
accountId: z.number().optional(),
|
|
10
|
+
valid: z.boolean(),
|
|
11
|
+
});
|
|
12
|
+
export const ValidateSchema = z.object({
|
|
13
|
+
valid: z.boolean(),
|
|
14
|
+
projectName: z.string().optional(),
|
|
15
|
+
platformVersion: z.string().optional(),
|
|
16
|
+
profile: z.string().optional(),
|
|
17
|
+
errors: z.array(ValidationIssueSchema),
|
|
18
|
+
warnings: z.array(ValidationIssueSchema),
|
|
19
|
+
profiles: z.array(ProfileValidationSchema).optional(),
|
|
20
|
+
});
|
package/lib/npm/packageJson.js
CHANGED
|
@@ -92,7 +92,7 @@ const findAllPackageJsonFilesInDirectoryCached = async (directory) => {
|
|
|
92
92
|
* @returns Array of absolute paths to package.json files in the project
|
|
93
93
|
*/
|
|
94
94
|
export async function findAllPackageJsonFilesInProjectCached() {
|
|
95
|
-
const projectConfig =
|
|
95
|
+
const projectConfig = getProjectConfig();
|
|
96
96
|
const { projectDir } = projectConfig;
|
|
97
97
|
if (!projectDir) {
|
|
98
98
|
return [];
|
|
@@ -34,10 +34,7 @@ class _ProjectLogsManager {
|
|
|
34
34
|
this.functions = [];
|
|
35
35
|
}
|
|
36
36
|
async init(accountId) {
|
|
37
|
-
const { projectConfig } =
|
|
38
|
-
if (!projectConfig || !projectConfig.name) {
|
|
39
|
-
throw new Error(commands.project.logs.errors.noProjectConfig);
|
|
40
|
-
}
|
|
37
|
+
const { projectConfig } = getProjectConfig();
|
|
41
38
|
this.projectConfig = projectConfig;
|
|
42
39
|
this.projectName = projectConfig.name;
|
|
43
40
|
this.accountId = accountId;
|
package/lib/projects/config.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ProjectConfig } from '
|
|
1
|
+
import type { ProjectConfig } from '@hubspot/project-parsing-lib/projects';
|
|
2
|
+
export { ProjectConfigValidationError } from '@hubspot/project-parsing-lib/projects';
|
|
3
|
+
export type { ProjectConfig } from '@hubspot/project-parsing-lib/projects';
|
|
2
4
|
export declare function writeProjectConfig(configPath: string, config: ProjectConfig): boolean;
|
|
3
5
|
export declare function getIsInProject(dir?: string): boolean;
|
|
4
6
|
export interface LoadedProjectConfig {
|
|
5
|
-
projectDir: string
|
|
6
|
-
projectConfig: ProjectConfig
|
|
7
|
+
projectDir: string;
|
|
8
|
+
projectConfig: ProjectConfig;
|
|
7
9
|
}
|
|
8
|
-
export declare function getProjectConfig(dir?: string):
|
|
9
|
-
export declare function validateProjectConfig(projectConfig: ProjectConfig | null, projectDir: string | null): asserts projectConfig is ProjectConfig;
|
|
10
|
+
export declare function getProjectConfig(dir?: string): LoadedProjectConfig;
|
package/lib/projects/config.js
CHANGED
|
@@ -2,10 +2,11 @@ import fs from 'fs-extra';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import findup from 'findup-sync';
|
|
4
4
|
import { getAbsoluteFilePath, getCwd } from '@hubspot/local-dev-lib/path';
|
|
5
|
+
import { parseProjectConfig, ProjectConfigValidationError, } from '@hubspot/project-parsing-lib/projects';
|
|
5
6
|
import { PROJECT_CONFIG_FILE } from '../constants.js';
|
|
6
7
|
import { lib } from '../../lang/en.js';
|
|
7
8
|
import { uiLogger } from '../ui/logger.js';
|
|
8
|
-
|
|
9
|
+
export { ProjectConfigValidationError } from '@hubspot/project-parsing-lib/projects';
|
|
9
10
|
export function writeProjectConfig(configPath, config) {
|
|
10
11
|
try {
|
|
11
12
|
fs.ensureFileSync(configPath);
|
|
@@ -30,44 +31,12 @@ function getProjectConfigPath(dir) {
|
|
|
30
31
|
});
|
|
31
32
|
return configPath;
|
|
32
33
|
}
|
|
33
|
-
export
|
|
34
|
+
export function getProjectConfig(dir) {
|
|
34
35
|
const configPath = getProjectConfigPath(dir);
|
|
35
36
|
if (!configPath) {
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
try {
|
|
39
|
-
const config = fs.readFileSync(configPath);
|
|
40
|
-
const projectConfig = JSON.parse(config.toString());
|
|
41
|
-
return {
|
|
42
|
-
projectDir: path.dirname(configPath),
|
|
43
|
-
projectConfig,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
catch (e) {
|
|
47
|
-
uiLogger.error(lib.projects.getProjectConfig.error);
|
|
48
|
-
return { projectConfig: null, projectDir: null };
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
export function validateProjectConfig(projectConfig, projectDir) {
|
|
52
|
-
if (!projectConfig || !projectDir) {
|
|
53
|
-
throw new ProjectValidationError(lib.projects.validateProjectConfig.configNotFound);
|
|
54
|
-
}
|
|
55
|
-
const missingFields = [];
|
|
56
|
-
if (!projectConfig.name) {
|
|
57
|
-
missingFields.push('name');
|
|
58
|
-
}
|
|
59
|
-
if (!projectConfig.srcDir) {
|
|
60
|
-
missingFields.push('srcDir');
|
|
61
|
-
}
|
|
62
|
-
if (missingFields.length > 0) {
|
|
63
|
-
throw new ProjectValidationError(lib.projects.validateProjectConfig.configMissingFields(missingFields));
|
|
64
|
-
}
|
|
65
|
-
const resolvedPath = path.resolve(projectDir, projectConfig.srcDir);
|
|
66
|
-
if (!resolvedPath.startsWith(projectDir)) {
|
|
67
|
-
const projectConfigFile = path.relative('.', path.join(projectDir, PROJECT_CONFIG_FILE));
|
|
68
|
-
throw new ProjectValidationError(lib.projects.validateProjectConfig.srcOutsideProjectDir(projectConfigFile, projectConfig.srcDir));
|
|
69
|
-
}
|
|
70
|
-
if (!fs.existsSync(resolvedPath)) {
|
|
71
|
-
throw new ProjectValidationError(lib.projects.validateProjectConfig.srcDirNotFound(projectConfig.srcDir, projectDir));
|
|
37
|
+
throw new ProjectConfigValidationError(lib.projects.validateProjectConfig.configNotFound);
|
|
72
38
|
}
|
|
39
|
+
const projectDir = path.dirname(configPath);
|
|
40
|
+
const projectConfig = parseProjectConfig(projectDir);
|
|
41
|
+
return { projectDir, projectConfig };
|
|
73
42
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getProjectCreateFailureReason(error: unknown): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { isFileSystemError, isGithubRateLimitError, isGithubError, getHttpStatusFromError, } from '@hubspot/local-dev-lib/errors/index';
|
|
2
|
+
const FAILURE_REASON = {
|
|
3
|
+
GITHUB_RATE_LIMIT: 'github-rate-limit',
|
|
4
|
+
GITHUB_NOT_FOUND: 'github-not-found',
|
|
5
|
+
GITHUB_ERROR: 'github-error',
|
|
6
|
+
HTTP_ERROR: 'http-error',
|
|
7
|
+
FILESYSTEM: 'filesystem',
|
|
8
|
+
UNKNOWN: 'unknown',
|
|
9
|
+
};
|
|
10
|
+
export function getProjectCreateFailureReason(error) {
|
|
11
|
+
if (isGithubRateLimitError(error)) {
|
|
12
|
+
return FAILURE_REASON.GITHUB_RATE_LIMIT;
|
|
13
|
+
}
|
|
14
|
+
const httpStatus = getHttpStatusFromError(error);
|
|
15
|
+
if (httpStatus !== undefined) {
|
|
16
|
+
if (isGithubError(error)) {
|
|
17
|
+
return httpStatus === 404
|
|
18
|
+
? FAILURE_REASON.GITHUB_NOT_FOUND
|
|
19
|
+
: FAILURE_REASON.GITHUB_ERROR;
|
|
20
|
+
}
|
|
21
|
+
return FAILURE_REASON.HTTP_ERROR;
|
|
22
|
+
}
|
|
23
|
+
if (isFileSystemError(error)) {
|
|
24
|
+
return FAILURE_REASON.FILESYSTEM;
|
|
25
|
+
}
|
|
26
|
+
return FAILURE_REASON.UNKNOWN;
|
|
27
|
+
}
|
package/lib/projects/delete.js
CHANGED
|
@@ -79,7 +79,20 @@ export async function checkDeployedComponents(accountId, projectName) {
|
|
|
79
79
|
const platformVersion = projectData.deployedBuild?.platformVersion ||
|
|
80
80
|
projectData.latestBuild?.platformVersion;
|
|
81
81
|
if (!platformVersion) {
|
|
82
|
-
|
|
82
|
+
// A build exists but carries no platform version. That is inconsistent data rather than an
|
|
83
|
+
// empty project, and the build may have deployed components, so keep failing loudly instead of
|
|
84
|
+
// silently skipping cleanup.
|
|
85
|
+
if (projectData.deployedBuild || projectData.latestBuild) {
|
|
86
|
+
throw new Error(commands.project.delete.errors.noPlatformVersion);
|
|
87
|
+
}
|
|
88
|
+
// No builds at all, so nothing is deployed and there is no platform version to branch on. This
|
|
89
|
+
// happens whenever a project's very first upload fails, for example on a platform version that
|
|
90
|
+
// is not active, and previously left the project impossible to delete.
|
|
91
|
+
return {
|
|
92
|
+
platformVersion: '',
|
|
93
|
+
hasUnifiedComponents: false,
|
|
94
|
+
projectId: projectData.id,
|
|
95
|
+
};
|
|
83
96
|
}
|
|
84
97
|
if (isLegacyProject(platformVersion)) {
|
|
85
98
|
const userVisibleComponents = [];
|
|
@@ -108,17 +108,17 @@ class LocalDevProcess {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
async projectConfigValidForUpload() {
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
let projectConfig;
|
|
112
|
+
try {
|
|
113
|
+
({ projectConfig } = getProjectConfig());
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
113
116
|
return false;
|
|
114
117
|
}
|
|
115
|
-
Object.keys(projectConfig).
|
|
118
|
+
return Object.keys(projectConfig).every(key => {
|
|
116
119
|
const field = key;
|
|
117
|
-
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
+
return projectConfig[field] === this.state.projectConfig[field];
|
|
120
121
|
});
|
|
121
|
-
return true;
|
|
122
122
|
}
|
|
123
123
|
async getIntermediateRepresentation(projectNodesAtLastDeploy) {
|
|
124
124
|
const { intermediateRepresentation } = await translateForLocalDev({
|
|
@@ -2,8 +2,9 @@ import { type HsProfileFile } from '@hubspot/project-parsing-lib/profiles';
|
|
|
2
2
|
import { ProjectConfig } from '../../types/Projects.js';
|
|
3
3
|
export declare function logProfileHeader(profileName: string): void;
|
|
4
4
|
export declare function logProfileFooter(profile: HsProfileFile, includeVariables?: boolean): void;
|
|
5
|
-
export declare function loadProfile(projectConfig: ProjectConfig
|
|
6
|
-
export declare function
|
|
5
|
+
export declare function loadProfile(projectConfig: ProjectConfig, projectDir: string, profileName: string): HsProfileFile | never;
|
|
6
|
+
export declare function getProfileAccountId(projectConfig: ProjectConfig, projectDir: string, profileName: string): number | undefined;
|
|
7
|
+
export declare function loadAndValidateProfile(projectConfig: ProjectConfig, projectDir: string, profileName: string, silent?: boolean): Promise<HsProfileFile | never>;
|
|
7
8
|
type ValidateProjectForProfileOptions = {
|
|
8
9
|
projectConfig: ProjectConfig;
|
|
9
10
|
projectDir: string;
|
|
@@ -25,9 +25,6 @@ export function logProfileFooter(profile, includeVariables = false) {
|
|
|
25
25
|
uiLogger.log('');
|
|
26
26
|
}
|
|
27
27
|
export function loadProfile(projectConfig, projectDir, profileName) {
|
|
28
|
-
if (!projectConfig || !projectDir) {
|
|
29
|
-
throw new Error(lib.projectProfiles.loadProfile.errors.noProjectConfig);
|
|
30
|
-
}
|
|
31
28
|
const projectSourceDir = path.join(projectDir, projectConfig.srcDir);
|
|
32
29
|
const profileFilename = getHsProfileFilename(profileName);
|
|
33
30
|
let profile;
|
|
@@ -51,6 +48,14 @@ export function loadProfile(projectConfig, projectDir, profileName) {
|
|
|
51
48
|
}
|
|
52
49
|
return profile;
|
|
53
50
|
}
|
|
51
|
+
export function getProfileAccountId(projectConfig, projectDir, profileName) {
|
|
52
|
+
try {
|
|
53
|
+
return loadProfile(projectConfig, projectDir, profileName).accountId;
|
|
54
|
+
}
|
|
55
|
+
catch (_e) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
54
59
|
export async function loadAndValidateProfile(projectConfig, projectDir, profileName, silent = false) {
|
|
55
60
|
if (!silent) {
|
|
56
61
|
logProfileHeader(profileName);
|
package/lib/projects/release.js
CHANGED
|
@@ -60,7 +60,7 @@ export async function resolveBuildId(accountId, projectName, buildOption, force)
|
|
|
60
60
|
export async function validateBuildForRelease(accountId, projectName, buildId) {
|
|
61
61
|
try {
|
|
62
62
|
const { data: build } = await getBuildStatus(accountId, projectName, buildId);
|
|
63
|
-
return meetsMinimumPlatformVersion(build.platformVersion, PLATFORM_VERSIONS.
|
|
63
|
+
return meetsMinimumPlatformVersion(build.platformVersion, PLATFORM_VERSIONS.v2027_03);
|
|
64
64
|
}
|
|
65
65
|
catch (e) {
|
|
66
66
|
if (isSpecifiedError(e, { statusCode: 404 })) {
|
|
@@ -24,6 +24,8 @@ export declare function hasEslintConfig(directory: string): boolean;
|
|
|
24
24
|
export declare function hasDeprecatedEslintConfig(directory: string): boolean;
|
|
25
25
|
export declare function getDeprecatedEslintConfigFiles(directory: string): string[];
|
|
26
26
|
export declare function createEslintConfig(directory: string, platformVersion?: string | null): Promise<string>;
|
|
27
|
+
export declare function getUieComponentDirPrefixes(srcDir: string): string[];
|
|
28
|
+
export declare function isUieComponentDirectory(directory: string, srcDir: string): boolean;
|
|
27
29
|
export declare function getUieLintablePackageJsonLocations(projectConfig: LoadedProjectConfig): Promise<string[]>;
|
|
28
30
|
export declare const HUBSPOT_UI_EXTENSIONS_RULE_PREFIX = "@hubspot/ui-extensions/";
|
|
29
31
|
export declare function isHubSpotEslintConfigActive(directory: string): Promise<boolean>;
|
|
@@ -9,9 +9,10 @@ import { commands } from '../../lang/en.js';
|
|
|
9
9
|
import { uiLogger } from '../ui/logger.js';
|
|
10
10
|
import { clearPackageJsonCache, safeGetPackageJsonCached, } from '../npm/packageJson.js';
|
|
11
11
|
import { debugError } from '../errorHandlers/index.js';
|
|
12
|
+
import { isPathInsideDirectory } from '../filesystem.js';
|
|
12
13
|
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
13
14
|
import { DEFAULT_PROJECT_TEMPLATE_BRANCH, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, } from '../constants.js';
|
|
14
|
-
import { CARDS_KEY, Components, PAGES_KEY, SETTINGS_KEY, } from '@hubspot/project-parsing-lib/constants';
|
|
15
|
+
import { ACTIONS_KEY, CARDS_KEY, Components, PAGES_KEY, SETTINGS_KEY, } from '@hubspot/project-parsing-lib/constants';
|
|
15
16
|
export const REQUIRED_PACKAGES_AND_MIN_VERSIONS = {
|
|
16
17
|
eslint: '9.0.0',
|
|
17
18
|
'@eslint/js': '9.0.0',
|
|
@@ -42,6 +43,7 @@ const DEPRECATED_ESLINT_CONFIG_FILES = [
|
|
|
42
43
|
'.eslintrc',
|
|
43
44
|
];
|
|
44
45
|
const UIE_COMPONENTS = [
|
|
46
|
+
Components[ACTIONS_KEY],
|
|
45
47
|
Components[CARDS_KEY],
|
|
46
48
|
Components[SETTINGS_KEY],
|
|
47
49
|
Components[PAGES_KEY],
|
|
@@ -169,19 +171,19 @@ export async function createEslintConfig(directory, platformVersion) {
|
|
|
169
171
|
throw error;
|
|
170
172
|
}
|
|
171
173
|
}
|
|
172
|
-
export
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
const srcDirAbsolute = path.resolve(projectConfig.projectDir, projectConfig.projectConfig.srcDir);
|
|
177
|
-
const uiePackageDirPrefixes = UIE_COMPONENTS.map(component => path.join(srcDirAbsolute, component.parentComponent
|
|
174
|
+
export function getUieComponentDirPrefixes(srcDir) {
|
|
175
|
+
const srcDirAbsolute = path.resolve(srcDir);
|
|
176
|
+
return UIE_COMPONENTS.map(component => path.join(srcDirAbsolute, component.parentComponent
|
|
178
177
|
? Components[component.parentComponent].dir
|
|
179
178
|
: '', component.dir));
|
|
179
|
+
}
|
|
180
|
+
export function isUieComponentDirectory(directory, srcDir) {
|
|
181
|
+
return getUieComponentDirPrefixes(srcDir).some(componentDir => isPathInsideDirectory(directory, componentDir));
|
|
182
|
+
}
|
|
183
|
+
export async function getUieLintablePackageJsonLocations(projectConfig) {
|
|
184
|
+
const srcDirAbsolute = path.resolve(projectConfig.projectDir, projectConfig.projectConfig.srcDir);
|
|
180
185
|
const allLocations = await getProjectPackageJsonLocations(projectConfig.projectDir);
|
|
181
|
-
return allLocations.filter(location =>
|
|
182
|
-
const resolvedLocation = path.resolve(location);
|
|
183
|
-
return uiePackageDirPrefixes.some(prefix => resolvedLocation.startsWith(prefix));
|
|
184
|
-
});
|
|
186
|
+
return allLocations.filter(location => isUieComponentDirectory(location, srcDirAbsolute));
|
|
185
187
|
}
|
|
186
188
|
export const HUBSPOT_UI_EXTENSIONS_RULE_PREFIX = '@hubspot/ui-extensions/';
|
|
187
189
|
function getEnvironmentWithoutNpmConfig() {
|
package/lib/projects/upload.d.ts
CHANGED
|
@@ -25,7 +25,11 @@ type HandleProjectUploadArg<T> = {
|
|
|
25
25
|
force?: boolean;
|
|
26
26
|
};
|
|
27
27
|
export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, skipNpmAudit, skipAutoDeploy, force, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
|
|
28
|
-
export
|
|
28
|
+
export type SourceDirectoryWarning = {
|
|
29
|
+
message: string;
|
|
30
|
+
file: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig, projectDir: string): Promise<SourceDirectoryWarning[]>;
|
|
29
33
|
export declare function validateNoHSMetaMismatch(srcDir: string, projectConfig: ProjectConfig): Promise<void>;
|
|
30
34
|
type HandleTranslateArg = {
|
|
31
35
|
projectDir: string;
|
package/lib/projects/upload.js
CHANGED
|
@@ -159,14 +159,19 @@ export async function validateSourceDirectory(srcDir, projectConfig, projectDir)
|
|
|
159
159
|
if (!projectFilePaths || projectFilePaths.length === 0) {
|
|
160
160
|
throw new ProjectValidationError(lib.projectUpload.handleProjectUpload.emptySource(projectConfig.srcDir));
|
|
161
161
|
}
|
|
162
|
+
const warnings = [];
|
|
162
163
|
if (!isLegacyProject(projectConfig.platformVersion)) {
|
|
163
164
|
projectFilePaths.forEach(filePath => {
|
|
164
165
|
const filename = path.basename(filePath);
|
|
165
166
|
if (LEGACY_CONFIG_FILES.includes(filename)) {
|
|
166
|
-
|
|
167
|
+
const relativePath = path.relative(projectDir, filePath);
|
|
168
|
+
const message = lib.projectUpload.handleProjectUpload.legacyFileDetected(relativePath, projectConfig.platformVersion);
|
|
169
|
+
warnings.push({ message, file: relativePath });
|
|
170
|
+
uiLogger.warn(message);
|
|
167
171
|
}
|
|
168
172
|
});
|
|
169
173
|
}
|
|
174
|
+
return warnings;
|
|
170
175
|
}
|
|
171
176
|
export async function validateNoHSMetaMismatch(srcDir, projectConfig) {
|
|
172
177
|
const hasHsMetaFiles = await projectContainsHsMetaFiles(srcDir);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ProjectConfig } from '../../types/Projects.js';
|
|
2
|
+
import { ProfileValidationJsonOutput, ValidationIssueJsonOutput } from '../jsonOutput/validate.js';
|
|
3
|
+
export type ProjectValidationResult = {
|
|
4
|
+
valid: boolean;
|
|
5
|
+
errors: ValidationIssueJsonOutput[];
|
|
6
|
+
warnings: ValidationIssueJsonOutput[];
|
|
7
|
+
profiles: ProfileValidationJsonOutput[];
|
|
8
|
+
};
|
|
9
|
+
type ValidateProjectArgs = {
|
|
10
|
+
projectConfig: ProjectConfig;
|
|
11
|
+
projectDir: string;
|
|
12
|
+
derivedAccountId: number;
|
|
13
|
+
profile?: string;
|
|
14
|
+
formatOutputAsJson?: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare function toIssue(error: unknown, profile?: string): ValidationIssueJsonOutput;
|
|
17
|
+
export declare function validateProject({ projectConfig, projectDir, derivedAccountId, profile, formatOutputAsJson, }: ValidateProjectArgs): Promise<ProjectValidationResult>;
|
|
18
|
+
export {};
|