@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.
Files changed (91) hide show
  1. package/commands/cms/theme/preview.js +8 -1
  2. package/commands/getStarted.js +15 -20
  3. package/commands/project/add.js +7 -6
  4. package/commands/project/appInstallStatus.d.ts +1 -1
  5. package/commands/project/appInstallStatus.js +8 -4
  6. package/commands/project/create.js +20 -6
  7. package/commands/project/delete.js +1 -1
  8. package/commands/project/deploy.d.ts +1 -1
  9. package/commands/project/deploy.js +14 -12
  10. package/commands/project/dev/index.js +4 -7
  11. package/commands/project/download.js +3 -3
  12. package/commands/project/info.d.ts +1 -1
  13. package/commands/project/info.js +8 -5
  14. package/commands/project/installApp.d.ts +1 -1
  15. package/commands/project/installApp.js +9 -4
  16. package/commands/project/installDeps.js +6 -5
  17. package/commands/project/lint.js +16 -9
  18. package/commands/project/list.d.ts +3 -2
  19. package/commands/project/list.js +21 -3
  20. package/commands/project/listBuilds.d.ts +1 -1
  21. package/commands/project/listBuilds.js +4 -8
  22. package/commands/project/migrate.js +14 -12
  23. package/commands/project/open.js +15 -7
  24. package/commands/project/profile/add.js +8 -4
  25. package/commands/project/profile/delete.js +8 -4
  26. package/commands/project/release/create.d.ts +1 -1
  27. package/commands/project/release/create.js +5 -7
  28. package/commands/project/release/info.d.ts +1 -1
  29. package/commands/project/release/info.js +4 -4
  30. package/commands/project/release/list.d.ts +1 -1
  31. package/commands/project/release/list.js +4 -4
  32. package/commands/project/updateDeps.js +6 -5
  33. package/commands/project/upload.d.ts +1 -1
  34. package/commands/project/upload.js +26 -15
  35. package/commands/project/validate.js +14 -97
  36. package/commands/project/watch.js +8 -11
  37. package/commands/project.js +1 -1
  38. package/commands/testAccount/create.d.ts +1 -1
  39. package/commands/testAccount/create.js +1 -1
  40. package/lang/en.d.ts +7 -18
  41. package/lang/en.js +7 -18
  42. package/lib/app/migrate.js +5 -7
  43. package/lib/dependencyManagement.js +3 -10
  44. package/lib/doctor/DiagnosticInfoBuilder.d.ts +2 -2
  45. package/lib/doctor/DiagnosticInfoBuilder.js +8 -8
  46. package/lib/doctor/Doctor.js +7 -9
  47. package/lib/errors/ProjectErrors.d.ts +0 -6
  48. package/lib/errors/ProjectErrors.js +0 -12
  49. package/lib/errors/ProjectValidationError.d.ts +2 -1
  50. package/lib/errors/ProjectValidationError.js +3 -1
  51. package/lib/getStartedV2Actions.js +14 -18
  52. package/lib/jsonOutput/appInstallStatus.d.ts +14 -0
  53. package/lib/jsonOutput/appInstallStatus.js +14 -0
  54. package/lib/jsonOutput/createTestAccount.d.ts +7 -0
  55. package/lib/jsonOutput/createTestAccount.js +6 -0
  56. package/lib/jsonOutput/deploy.d.ts +5 -0
  57. package/lib/jsonOutput/deploy.js +4 -0
  58. package/lib/jsonOutput/info.d.ts +21 -0
  59. package/lib/jsonOutput/info.js +19 -0
  60. package/lib/jsonOutput/installApp.d.ts +11 -0
  61. package/lib/jsonOutput/installApp.js +10 -0
  62. package/lib/jsonOutput/listBuilds.d.ts +75 -0
  63. package/lib/jsonOutput/listBuilds.js +65 -0
  64. package/lib/jsonOutput/projectList.d.ts +29 -0
  65. package/lib/jsonOutput/projectList.js +28 -0
  66. package/lib/jsonOutput/release.d.ts +42 -0
  67. package/lib/jsonOutput/release.js +37 -0
  68. package/lib/jsonOutput/upload.d.ts +29 -0
  69. package/lib/jsonOutput/upload.js +23 -0
  70. package/lib/npm/packageJson.js +1 -1
  71. package/lib/projects/ProjectLogsManager.js +1 -4
  72. package/lib/projects/config.d.ts +6 -5
  73. package/lib/projects/config.js +7 -38
  74. package/lib/projects/create/tracking.d.ts +1 -0
  75. package/lib/projects/create/tracking.js +27 -0
  76. package/lib/projects/delete.js +14 -1
  77. package/lib/projects/localDev/LocalDevProcess.js +7 -7
  78. package/lib/projects/projectProfiles.d.ts +2 -2
  79. package/lib/projects/projectProfiles.js +0 -3
  80. package/lib/projects/release.js +1 -1
  81. package/lib/projects/uieLinting.js +0 -3
  82. package/lib/projects/validate.d.ts +9 -0
  83. package/lib/projects/validate.js +96 -0
  84. package/lib/theme/migrate.js +1 -4
  85. package/mcp-server/tools/project/GetBuildLogsTool.js +2 -3
  86. package/mcp-server/tools/project/GetBuildStatusTool.js +2 -3
  87. package/mcp-server/tools/project/UploadProjectTools.js +3 -5
  88. package/package.json +3 -3
  89. package/types/Projects.d.ts +1 -5
  90. package/lib/jsonOutput.d.ts +0 -182
  91. package/lib/jsonOutput.js +0 -158
@@ -0,0 +1,19 @@
1
+ import { z } from 'zod';
2
+ export const ProjectInfoSchema = z.object({
3
+ projectName: z.string(),
4
+ platformVersion: z.string(),
5
+ projectId: z.number(),
6
+ deployedBuildId: z.number(),
7
+ autoDeployEnabled: z.boolean(),
8
+ projectUrl: z.string().optional(),
9
+ app: z
10
+ .object({
11
+ name: z.string(),
12
+ id: z.number(),
13
+ uid: z.string(),
14
+ authType: z.string().optional(),
15
+ distributionType: z.string().optional(),
16
+ })
17
+ .optional(),
18
+ components: z.array(z.object({ uid: z.string(), type: z.string() })),
19
+ });
@@ -0,0 +1,11 @@
1
+ import { z } from 'zod';
2
+ export declare const InstallAppSchema: z.ZodObject<{
3
+ appId: z.ZodNumber;
4
+ appUid: z.ZodString;
5
+ accountId: z.ZodNumber;
6
+ projectId: z.ZodNumber;
7
+ installationState: z.ZodString;
8
+ installed: z.ZodBoolean;
9
+ reinstalled: z.ZodBoolean;
10
+ }, z.core.$strip>;
11
+ export type InstallAppJsonOutput = z.infer<typeof InstallAppSchema>;
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ export const InstallAppSchema = z.object({
3
+ appId: z.number(),
4
+ appUid: z.string(),
5
+ accountId: z.number(),
6
+ projectId: z.number(),
7
+ installationState: z.string(),
8
+ installed: z.boolean(),
9
+ reinstalled: z.boolean(),
10
+ });
@@ -0,0 +1,75 @@
1
+ import { z } from 'zod';
2
+ import { Build } from '@hubspot/local-dev-lib/types/Build';
3
+ declare const BuildSubbuildStatusSchema: z.ZodObject<{
4
+ buildName: z.ZodString;
5
+ buildType: z.ZodString;
6
+ status: z.ZodString;
7
+ errorMessage: z.ZodOptional<z.ZodString>;
8
+ startedAt: z.ZodOptional<z.ZodString>;
9
+ finishedAt: z.ZodOptional<z.ZodString>;
10
+ rootPath: z.ZodOptional<z.ZodString>;
11
+ id: z.ZodOptional<z.ZodString>;
12
+ visible: z.ZodOptional<z.ZodBoolean>;
13
+ }, z.core.$strip>;
14
+ export declare const BuildSchema: z.ZodObject<{
15
+ buildId: z.ZodNumber;
16
+ status: z.ZodString;
17
+ isDeployed: z.ZodBoolean;
18
+ isAutoDeployEnabled: z.ZodOptional<z.ZodBoolean>;
19
+ deployableState: z.ZodOptional<z.ZodString>;
20
+ platformVersion: z.ZodOptional<z.ZodString>;
21
+ uploadMessage: z.ZodOptional<z.ZodString>;
22
+ enqueuedAt: z.ZodOptional<z.ZodString>;
23
+ startedAt: z.ZodOptional<z.ZodString>;
24
+ finishedAt: z.ZodOptional<z.ZodString>;
25
+ createdAt: z.ZodOptional<z.ZodString>;
26
+ subbuildStatuses: z.ZodArray<z.ZodObject<{
27
+ buildName: z.ZodString;
28
+ buildType: z.ZodString;
29
+ status: z.ZodString;
30
+ errorMessage: z.ZodOptional<z.ZodString>;
31
+ startedAt: z.ZodOptional<z.ZodString>;
32
+ finishedAt: z.ZodOptional<z.ZodString>;
33
+ rootPath: z.ZodOptional<z.ZodString>;
34
+ id: z.ZodOptional<z.ZodString>;
35
+ visible: z.ZodOptional<z.ZodBoolean>;
36
+ }, z.core.$strip>>;
37
+ }, z.core.$strip>;
38
+ export declare const ProjectBuildsListSchema: z.ZodObject<{
39
+ projectName: z.ZodString;
40
+ deployedBuildId: z.ZodOptional<z.ZodNumber>;
41
+ results: z.ZodArray<z.ZodObject<{
42
+ buildId: z.ZodNumber;
43
+ status: z.ZodString;
44
+ isDeployed: z.ZodBoolean;
45
+ isAutoDeployEnabled: z.ZodOptional<z.ZodBoolean>;
46
+ deployableState: z.ZodOptional<z.ZodString>;
47
+ platformVersion: z.ZodOptional<z.ZodString>;
48
+ uploadMessage: z.ZodOptional<z.ZodString>;
49
+ enqueuedAt: z.ZodOptional<z.ZodString>;
50
+ startedAt: z.ZodOptional<z.ZodString>;
51
+ finishedAt: z.ZodOptional<z.ZodString>;
52
+ createdAt: z.ZodOptional<z.ZodString>;
53
+ subbuildStatuses: z.ZodArray<z.ZodObject<{
54
+ buildName: z.ZodString;
55
+ buildType: z.ZodString;
56
+ status: z.ZodString;
57
+ errorMessage: z.ZodOptional<z.ZodString>;
58
+ startedAt: z.ZodOptional<z.ZodString>;
59
+ finishedAt: z.ZodOptional<z.ZodString>;
60
+ rootPath: z.ZodOptional<z.ZodString>;
61
+ id: z.ZodOptional<z.ZodString>;
62
+ visible: z.ZodOptional<z.ZodBoolean>;
63
+ }, z.core.$strip>>;
64
+ }, z.core.$strip>>;
65
+ paging: z.ZodOptional<z.ZodObject<{
66
+ next: z.ZodObject<{
67
+ after: z.ZodString;
68
+ }, z.core.$strip>;
69
+ }, z.core.$strip>>;
70
+ }, z.core.$strip>;
71
+ export type BuildSubbuildStatusJsonOutput = z.infer<typeof BuildSubbuildStatusSchema>;
72
+ export type BuildJsonOutput = z.infer<typeof BuildSchema>;
73
+ export type ProjectBuildsListJsonOutput = z.infer<typeof ProjectBuildsListSchema>;
74
+ export declare function mapBuildToJsonOutput(build: Build, deployedBuildId?: number): BuildJsonOutput;
75
+ export {};
@@ -0,0 +1,65 @@
1
+ import { z } from 'zod';
2
+ const BuildSubbuildStatusSchema = z.object({
3
+ buildName: z.string(),
4
+ buildType: z.string(),
5
+ status: z.string(),
6
+ errorMessage: z.string().optional(),
7
+ startedAt: z.string().optional(),
8
+ finishedAt: z.string().optional(),
9
+ rootPath: z.string().optional(),
10
+ id: z.string().optional(),
11
+ visible: z.boolean().optional(),
12
+ });
13
+ export const BuildSchema = z.object({
14
+ buildId: z.number(),
15
+ status: z.string(),
16
+ isDeployed: z.boolean(),
17
+ isAutoDeployEnabled: z.boolean().optional(),
18
+ deployableState: z.string().optional(),
19
+ platformVersion: z.string().optional(),
20
+ uploadMessage: z.string().optional(),
21
+ enqueuedAt: z.string().optional(),
22
+ startedAt: z.string().optional(),
23
+ finishedAt: z.string().optional(),
24
+ createdAt: z.string().optional(),
25
+ subbuildStatuses: z.array(BuildSubbuildStatusSchema),
26
+ });
27
+ export const ProjectBuildsListSchema = z.object({
28
+ projectName: z.string(),
29
+ deployedBuildId: z.number().optional(),
30
+ results: z.array(BuildSchema),
31
+ paging: z
32
+ .object({
33
+ next: z.object({
34
+ after: z.string(),
35
+ }),
36
+ })
37
+ .optional(),
38
+ });
39
+ export function mapBuildToJsonOutput(build, deployedBuildId) {
40
+ const { buildId, status, isAutoDeployEnabled, deployableState, platformVersion, uploadMessage, enqueuedAt, startedAt, finishedAt, createdAt, subbuildStatuses, } = build;
41
+ return {
42
+ buildId,
43
+ status,
44
+ isDeployed: buildId === deployedBuildId,
45
+ isAutoDeployEnabled,
46
+ deployableState,
47
+ platformVersion,
48
+ uploadMessage,
49
+ enqueuedAt,
50
+ startedAt,
51
+ finishedAt,
52
+ createdAt,
53
+ subbuildStatuses: subbuildStatuses.map(subbuild => ({
54
+ buildName: subbuild.buildName,
55
+ buildType: subbuild.buildType,
56
+ status: subbuild.status,
57
+ errorMessage: subbuild.errorMessage,
58
+ startedAt: subbuild.startedAt,
59
+ finishedAt: subbuild.finishedAt,
60
+ rootPath: subbuild.rootPath,
61
+ id: subbuild.id,
62
+ visible: subbuild.visible,
63
+ })),
64
+ };
65
+ }
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { Project } from '@hubspot/local-dev-lib/types/Project';
3
+ declare const ProjectListItemSchema: z.ZodObject<{
4
+ name: z.ZodString;
5
+ id: z.ZodNumber;
6
+ createdAt: z.ZodNumber;
7
+ updatedAt: z.ZodNumber;
8
+ platformVersion: z.ZodOptional<z.ZodString>;
9
+ latestBuildId: z.ZodOptional<z.ZodNumber>;
10
+ deployedBuildId: z.ZodOptional<z.ZodNumber>;
11
+ isLocked: z.ZodBoolean;
12
+ }, z.core.$strip>;
13
+ export declare const ProjectListSchema: z.ZodObject<{
14
+ accountId: z.ZodNumber;
15
+ results: z.ZodArray<z.ZodObject<{
16
+ name: z.ZodString;
17
+ id: z.ZodNumber;
18
+ createdAt: z.ZodNumber;
19
+ updatedAt: z.ZodNumber;
20
+ platformVersion: z.ZodOptional<z.ZodString>;
21
+ latestBuildId: z.ZodOptional<z.ZodNumber>;
22
+ deployedBuildId: z.ZodOptional<z.ZodNumber>;
23
+ isLocked: z.ZodBoolean;
24
+ }, z.core.$strip>>;
25
+ }, z.core.$strip>;
26
+ export type ProjectListItemJsonOutput = z.infer<typeof ProjectListItemSchema>;
27
+ export type ProjectListJsonOutput = z.infer<typeof ProjectListSchema>;
28
+ export declare function mapProjectToListItem(project: Project): ProjectListItemJsonOutput;
29
+ export {};
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ const ProjectListItemSchema = z.object({
3
+ name: z.string(),
4
+ id: z.number(),
5
+ createdAt: z.number(),
6
+ updatedAt: z.number(),
7
+ platformVersion: z.string().optional(),
8
+ latestBuildId: z.number().optional(),
9
+ deployedBuildId: z.number().optional(),
10
+ isLocked: z.boolean(),
11
+ });
12
+ export const ProjectListSchema = z.object({
13
+ accountId: z.number(),
14
+ results: z.array(ProjectListItemSchema),
15
+ });
16
+ export function mapProjectToListItem(project) {
17
+ const { name, id, createdAt, updatedAt, isLocked, latestBuild, deployedBuildId, } = project;
18
+ return {
19
+ name,
20
+ id,
21
+ createdAt,
22
+ updatedAt,
23
+ platformVersion: latestBuild?.platformVersion,
24
+ latestBuildId: latestBuild?.buildId,
25
+ deployedBuildId,
26
+ isLocked,
27
+ };
28
+ }
@@ -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
+ }
@@ -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 = await getProjectConfig();
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 } = await getProjectConfig();
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;
@@ -1,9 +1,10 @@
1
- import { ProjectConfig } from '../../types/Projects.js';
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 | null;
6
- projectConfig: ProjectConfig | null;
7
+ projectDir: string;
8
+ projectConfig: ProjectConfig;
7
9
  }
8
- export declare function getProjectConfig(dir?: string): Promise<LoadedProjectConfig>;
9
- export declare function validateProjectConfig(projectConfig: ProjectConfig | null, projectDir: string | null): asserts projectConfig is ProjectConfig;
10
+ export declare function getProjectConfig(dir?: string): LoadedProjectConfig;
@@ -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
- import ProjectValidationError from '../errors/ProjectValidationError.js';
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 async function getProjectConfig(dir) {
34
+ export function getProjectConfig(dir) {
34
35
  const configPath = getProjectConfigPath(dir);
35
36
  if (!configPath) {
36
- return { projectConfig: null, projectDir: null };
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
+ }
@@ -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
- throw new Error(commands.project.delete.errors.noPlatformVersion);
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
- const { projectConfig } = await getProjectConfig();
112
- if (!projectConfig) {
111
+ let projectConfig;
112
+ try {
113
+ ({ projectConfig } = getProjectConfig());
114
+ }
115
+ catch {
113
116
  return false;
114
117
  }
115
- Object.keys(projectConfig).forEach(key => {
118
+ return Object.keys(projectConfig).every(key => {
116
119
  const field = key;
117
- if (projectConfig[field] !== this.state.projectConfig[field]) {
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,8 @@ 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 | null, projectDir: string | null, profileName: string): HsProfileFile | never;
6
- export declare function loadAndValidateProfile(projectConfig: ProjectConfig | null, projectDir: string | null, profileName: string, silent?: boolean): Promise<HsProfileFile | never>;
5
+ export declare function loadProfile(projectConfig: ProjectConfig, projectDir: string, profileName: string): HsProfileFile | never;
6
+ export declare function loadAndValidateProfile(projectConfig: ProjectConfig, projectDir: string, profileName: string, silent?: boolean): Promise<HsProfileFile | never>;
7
7
  type ValidateProjectForProfileOptions = {
8
8
  projectConfig: ProjectConfig;
9
9
  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;
@@ -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.v2027_03_BETA);
63
+ return meetsMinimumPlatformVersion(build.platformVersion, PLATFORM_VERSIONS.v2027_03);
64
64
  }
65
65
  catch (e) {
66
66
  if (isSpecifiedError(e, { statusCode: 404 })) {
@@ -170,9 +170,6 @@ export async function createEslintConfig(directory, platformVersion) {
170
170
  }
171
171
  }
172
172
  export async function getUieLintablePackageJsonLocations(projectConfig) {
173
- if (!projectConfig.projectDir || !projectConfig.projectConfig?.srcDir) {
174
- return [];
175
- }
176
173
  const srcDirAbsolute = path.resolve(projectConfig.projectDir, projectConfig.projectConfig.srcDir);
177
174
  const uiePackageDirPrefixes = UIE_COMPONENTS.map(component => path.join(srcDirAbsolute, component.parentComponent
178
175
  ? Components[component.parentComponent].dir
@@ -0,0 +1,9 @@
1
+ import { ProjectConfig } from '../../types/Projects.js';
2
+ type ValidateProjectArgs = {
3
+ projectConfig: ProjectConfig;
4
+ projectDir: string;
5
+ derivedAccountId: number;
6
+ profile?: string;
7
+ };
8
+ export declare function validateProject({ projectConfig, projectDir, derivedAccountId, profile, }: ValidateProjectArgs): Promise<boolean>;
9
+ export {};