@hubspot/cli 8.4.0 → 8.5.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/api/migrate.js +3 -3
- package/bin/cli.js +3 -0
- package/commands/app/migrate.js +4 -4
- package/commands/getStarted.js +2 -2
- package/commands/project/add.js +3 -3
- package/commands/project/create.js +10 -7
- package/commands/project/delete.js +2 -2
- package/commands/project/deploy.js +4 -3
- package/commands/project/dev/index.js +5 -4
- package/commands/project/info.js +2 -2
- package/commands/project/migrate.js +5 -5
- package/commands/project/profile/add.js +2 -2
- package/commands/project/profile/delete.js +2 -2
- package/commands/project/upload.js +3 -3
- package/commands/project/validate.js +2 -2
- package/commands/project/watch.js +2 -2
- package/commands/project.js +6 -3
- package/commands/testAccount/create.js +4 -4
- package/lang/en.d.ts +11 -0
- package/lang/en.js +16 -5
- package/lib/app/migrate.js +7 -0
- package/lib/constants.d.ts +0 -1
- package/lib/constants.js +0 -1
- package/lib/doctor/Doctor.js +2 -2
- package/lib/getStartedV2Actions.js +2 -2
- package/lib/hasFeature.js +1 -2
- package/lib/middleware/autoUpdateMiddleware.js +6 -3
- package/lib/projects/ProjectLogsManager.js +6 -3
- package/lib/projects/create/index.js +2 -2
- package/lib/projects/create/legacy.js +2 -2
- package/lib/projects/create/v2.js +3 -4
- package/lib/projects/delete.js +2 -2
- package/lib/projects/deploy.d.ts +1 -1
- package/lib/projects/deploy.js +2 -2
- package/lib/projects/upload.js +22 -3
- package/lib/projects/workspaces.d.ts +42 -0
- package/lib/projects/workspaces.js +350 -0
- package/lib/prompts/projectsLogsPrompt.js +3 -0
- package/lib/theme/cmsDevServerProcess.js +1 -1
- package/mcp-server/Tool.d.ts +15 -0
- package/mcp-server/Tool.js +53 -0
- package/mcp-server/server.js +5 -3
- package/mcp-server/tools/cms/HsCreateFunctionTool.d.ts +4 -2
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +8 -6
- package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +4 -2
- package/mcp-server/tools/cms/HsCreateModuleTool.js +8 -6
- package/mcp-server/tools/cms/HsCreateTemplateTool.d.ts +4 -2
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +8 -6
- package/mcp-server/tools/cms/HsFunctionLogsTool.d.ts +4 -2
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +8 -6
- package/mcp-server/tools/cms/HsListFunctionsTool.d.ts +4 -2
- package/mcp-server/tools/cms/HsListFunctionsTool.js +8 -6
- package/mcp-server/tools/cms/HsListTool.d.ts +4 -2
- package/mcp-server/tools/cms/HsListTool.js +8 -6
- package/mcp-server/tools/index.d.ts +3 -2
- package/mcp-server/tools/index.js +22 -22
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +6 -4
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +8 -6
- package/mcp-server/tools/project/CreateProjectTool.d.ts +6 -4
- package/mcp-server/tools/project/CreateProjectTool.js +9 -7
- package/mcp-server/tools/project/CreateTestAccountTool.d.ts +4 -2
- package/mcp-server/tools/project/CreateTestAccountTool.js +20 -8
- package/mcp-server/tools/project/DeployProjectTool.d.ts +4 -2
- package/mcp-server/tools/project/DeployProjectTool.js +4 -6
- package/mcp-server/tools/project/DocFetchTool.d.ts +4 -2
- package/mcp-server/tools/project/DocFetchTool.js +8 -6
- package/mcp-server/tools/project/DocsSearchTool.d.ts +9 -3
- package/mcp-server/tools/project/DocsSearchTool.js +32 -9
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +4 -2
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +8 -6
- package/mcp-server/tools/project/GetApplicationInfoTool.d.ts +4 -2
- package/mcp-server/tools/project/GetApplicationInfoTool.js +8 -6
- package/mcp-server/tools/project/GetBuildLogsTool.d.ts +4 -2
- package/mcp-server/tools/project/GetBuildLogsTool.js +8 -6
- package/mcp-server/tools/project/GetBuildStatusTool.d.ts +4 -2
- package/mcp-server/tools/project/GetBuildStatusTool.js +8 -6
- package/mcp-server/tools/project/GetConfigValuesTool.d.ts +4 -2
- package/mcp-server/tools/project/GetConfigValuesTool.js +12 -7
- package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +4 -2
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +4 -6
- package/mcp-server/tools/project/UploadProjectTools.d.ts +4 -2
- package/mcp-server/tools/project/UploadProjectTools.js +9 -7
- package/mcp-server/tools/project/ValidateProjectTool.d.ts +4 -2
- package/mcp-server/tools/project/ValidateProjectTool.js +8 -6
- package/mcp-server/tools/project/constants.d.ts +2 -2
- package/mcp-server/types.d.ts +0 -7
- package/mcp-server/types.js +1 -13
- package/mcp-server/utils/logger.d.ts +10 -0
- package/mcp-server/utils/logger.js +29 -0
- package/mcp-server/utils/toolUsageTracking.js +0 -2
- package/package.json +10 -10
- package/lib/projects/platformVersion.d.ts +0 -9
- package/lib/projects/platformVersion.js +0 -39
package/lib/doctor/Doctor.js
CHANGED
|
@@ -26,7 +26,7 @@ import { isServerRunningAtUrl } from '../http.js';
|
|
|
26
26
|
import { WEBHOOKS_KEY, APP_KEY } from '@hubspot/project-parsing-lib/constants';
|
|
27
27
|
import { validateProjectConfig } from '../projects/config.js';
|
|
28
28
|
import { validateSourceDirectory, handleTranslate, } from '../projects/upload.js';
|
|
29
|
-
import {
|
|
29
|
+
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
30
30
|
import { validateProjectForProfile } from '../projects/projectProfiles.js';
|
|
31
31
|
import { getAllHsProfiles } from '@hubspot/project-parsing-lib/profiles';
|
|
32
32
|
const minMajorNodeVersion = 20;
|
|
@@ -534,7 +534,7 @@ export class Doctor {
|
|
|
534
534
|
if (!this.validateProjectConfigWrapper(projectConfig, projectDir)) {
|
|
535
535
|
return;
|
|
536
536
|
}
|
|
537
|
-
if (
|
|
537
|
+
if (isLegacyProject(projectConfig.platformVersion)) {
|
|
538
538
|
this.diagnosis?.addProjectSection({
|
|
539
539
|
type: 'success',
|
|
540
540
|
message: lib.doctor.projectValidation.valid,
|
|
@@ -13,7 +13,7 @@ import { getStaticAuthAppInstallUrl } from '../lib/app/urls.js';
|
|
|
13
13
|
import { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, PROJECT_CONFIG_FILE, } from '../lib/constants.js';
|
|
14
14
|
import { ProjectNestingError, ProjectConfigNotFoundError, ProjectValidationError, ProjectUploadError, ProjectBuildDeployError, } from './errors/ProjectErrors.js';
|
|
15
15
|
import { getProjectConfig, validateProjectConfig, writeProjectConfig, } from '../lib/projects/config.js';
|
|
16
|
-
import {
|
|
16
|
+
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
17
17
|
import { pollProjectBuildAndDeploy } from '../lib/projects/pollProjectBuildAndDeploy.js';
|
|
18
18
|
import { handleProjectUpload } from '../lib/projects/upload.js';
|
|
19
19
|
import { validateProjectDirectory } from '../lib/prompts/projectNameAndDestPrompt.js';
|
|
@@ -109,7 +109,7 @@ export async function uploadAndDeployAction({ accountId, projectDest, }) {
|
|
|
109
109
|
uploadMessage: commands.getStarted.logs.initialUploadMessage,
|
|
110
110
|
forceCreate: true,
|
|
111
111
|
isUploadCommand: false,
|
|
112
|
-
sendIR:
|
|
112
|
+
sendIR: !isLegacyProject(projectConfig.platformVersion),
|
|
113
113
|
skipValidation: false,
|
|
114
114
|
});
|
|
115
115
|
if (uploadError) {
|
package/lib/hasFeature.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { http } from '@hubspot/local-dev-lib/http';
|
|
2
2
|
import { fetchEnabledFeatures } from '@hubspot/local-dev-lib/api/localDevAuth';
|
|
3
|
-
|
|
4
|
-
const FEATURES_THAT_DEFAULT_ON = [FEATURES.APPS_HOME];
|
|
3
|
+
const FEATURES_THAT_DEFAULT_ON = [];
|
|
5
4
|
export async function hasFeature(accountId, feature) {
|
|
6
5
|
const { data: { enabledFeatures }, } = await fetchEnabledFeatures(accountId);
|
|
7
6
|
if (enabledFeatures[feature] === undefined &&
|
|
@@ -42,6 +42,10 @@ export async function autoUpdateCLI(argv) {
|
|
|
42
42
|
debugError(e);
|
|
43
43
|
}
|
|
44
44
|
const cliUpgradeInfo = getCliUpgradeInfo();
|
|
45
|
+
// Ignore all update notifications if the current version is a pre-release (contains a hyphen)
|
|
46
|
+
if (cliUpgradeInfo.current && cliUpgradeInfo.current.includes('-')) {
|
|
47
|
+
showManualInstallHelp = false;
|
|
48
|
+
}
|
|
45
49
|
if (isAllowAutoUpdatesEnabled &&
|
|
46
50
|
cliUpgradeInfo.current &&
|
|
47
51
|
cliUpgradeInfo.latest &&
|
|
@@ -49,9 +53,8 @@ export async function autoUpdateCLI(argv) {
|
|
|
49
53
|
!argv.useEnv &&
|
|
50
54
|
!process.env.SKIP_HUBSPOT_CLI_AUTO_UPDATES &&
|
|
51
55
|
!preventAutoUpdateForCommand(argv._)) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
showManualInstallHelp = false;
|
|
56
|
+
if (!showManualInstallHelp) {
|
|
57
|
+
// Pre-release version detected, skip auto-update
|
|
55
58
|
}
|
|
56
59
|
else if (!['major', 'latest'].includes(cliUpgradeInfo.type)) {
|
|
57
60
|
// type "latest" => current installed version is latest
|
|
@@ -4,7 +4,7 @@ import { fetchProjectComponentsMetadata } from '@hubspot/local-dev-lib/api/proje
|
|
|
4
4
|
import { fetchAppMetadataBySourceId } from '@hubspot/local-dev-lib/api/appsDev';
|
|
5
5
|
import { uiLogger } from '../ui/logger.js';
|
|
6
6
|
import { commands } from '../../lang/en.js';
|
|
7
|
-
import {
|
|
7
|
+
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
8
8
|
import { getDeployedProjectNodes } from './localDev/helpers/project.js';
|
|
9
9
|
import { debugError } from '../errorHandlers/index.js';
|
|
10
10
|
class _ProjectLogsManager {
|
|
@@ -51,7 +51,7 @@ class _ProjectLogsManager {
|
|
|
51
51
|
throw new Error(commands.project.logs.errors.failedToFetchProjectDetails);
|
|
52
52
|
}
|
|
53
53
|
this.projectId = project.id;
|
|
54
|
-
if (
|
|
54
|
+
if (!isLegacyProject(projectConfig.platformVersion)) {
|
|
55
55
|
const deployedBuildId = project.deployedBuild.buildId;
|
|
56
56
|
if (!deployedBuildId) {
|
|
57
57
|
throw new Error(commands.project.logs.errors.noDeployedBuild);
|
|
@@ -134,9 +134,12 @@ class _ProjectLogsManager {
|
|
|
134
134
|
return this.functions.map(serverlessFunction => serverlessFunction.componentName);
|
|
135
135
|
}
|
|
136
136
|
setFunction(functionName) {
|
|
137
|
-
if (
|
|
137
|
+
if (this.functions.length === 0) {
|
|
138
138
|
throw new Error(commands.project.logs.errors.noFunctionsInProject);
|
|
139
139
|
}
|
|
140
|
+
if (!functionName) {
|
|
141
|
+
throw new Error(commands.project.logs.errors.functionNameRequired);
|
|
142
|
+
}
|
|
140
143
|
this.selectedFunction = this.functions.find(serverlessFunction => serverlessFunction.componentName === functionName);
|
|
141
144
|
if (!this.selectedFunction) {
|
|
142
145
|
throw new Error(commands.project.logs.errors.noFunctionWithName(functionName));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { selectProjectTemplatePrompt, } from '../../prompts/selectProjectTemplatePrompt.js';
|
|
2
2
|
import { projectNameAndDestPrompt } from '../../prompts/projectNameAndDestPrompt.js';
|
|
3
3
|
import { DEFAULT_PROJECT_TEMPLATE_BRANCH, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, EMPTY_PROJECT, } from '../../constants.js';
|
|
4
|
-
import {
|
|
4
|
+
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
5
5
|
import { v2ComponentFlow } from './v2.js';
|
|
6
6
|
import { getProjectTemplateListFromRepo } from './legacy.js';
|
|
7
7
|
import { commands } from '../../../lang/en.js';
|
|
@@ -9,7 +9,7 @@ export async function handleProjectCreationFlow(args) {
|
|
|
9
9
|
const { platformVersion, templateSource, projectBase, auth: providedAuth, distribution: providedDistribution, } = args;
|
|
10
10
|
const repo = templateSource || HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH;
|
|
11
11
|
const projectNameAndDestPromptResponse = await projectNameAndDestPrompt(args);
|
|
12
|
-
if (
|
|
12
|
+
if (!isLegacyProject(platformVersion)) {
|
|
13
13
|
const { componentTemplateChoices, authType, distribution, repoConfig, projectContents, } = await v2ComponentFlow(platformVersion, projectBase, providedAuth, providedDistribution, args.derivedAccountId);
|
|
14
14
|
const selectProjectTemplatePromptResponse = await selectProjectTemplatePrompt(args, undefined, projectContents !== EMPTY_PROJECT ? componentTemplateChoices : undefined);
|
|
15
15
|
return {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { fetchRepoFile } from '@hubspot/local-dev-lib/api/github';
|
|
2
2
|
import { DEFAULT_PROJECT_TEMPLATE_BRANCH, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, PROJECT_COMPONENT_TYPES, } from '../../constants.js';
|
|
3
3
|
import { debugError } from '../../errorHandlers/index.js';
|
|
4
|
-
import {
|
|
4
|
+
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
5
5
|
import { lib } from '../../../lang/en.js';
|
|
6
6
|
const PROJECT_TEMPLATE_PROPERTIES = ['name', 'label', 'path'];
|
|
7
7
|
export const EMPTY_PROJECT_TEMPLATE_NAME = 'no-template';
|
|
8
8
|
export async function getConfigForPlatformVersion(platformVersion) {
|
|
9
9
|
let path = '';
|
|
10
|
-
if (
|
|
10
|
+
if (!isLegacyProject(platformVersion)) {
|
|
11
11
|
path = `${platformVersion}/`;
|
|
12
12
|
}
|
|
13
13
|
const { data } = await fetchRepoFile(HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, `${path}config.json`, DEFAULT_PROJECT_TEMPLATE_BRANCH);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { marketplaceDistribution, oAuth, privateDistribution, staticAuth, EMPTY_PROJECT, PROJECT_WITH_APP, FEATURES, } from '../../constants.js';
|
|
2
2
|
import { commands, lib } from '../../../lang/en.js';
|
|
3
3
|
import { listPrompt } from '../../prompts/promptUtils.js';
|
|
4
|
-
import { APP_EVENTS_KEY as AppEventsKey
|
|
5
|
-
import {
|
|
4
|
+
import { APP_EVENTS_KEY as AppEventsKey } from '@hubspot/project-parsing-lib/constants';
|
|
5
|
+
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { getConfigForPlatformVersion } from './legacy.js';
|
|
8
8
|
import { hasFeature } from '../../hasFeature.js';
|
|
@@ -47,7 +47,6 @@ export async function createV2App(providedAuth, providedDistribution) {
|
|
|
47
47
|
}
|
|
48
48
|
const componentTypeToGateMap = {
|
|
49
49
|
[AppEventsKey]: FEATURES.APP_EVENTS,
|
|
50
|
-
[PagesKey]: FEATURES.APPS_HOME,
|
|
51
50
|
'workflow-action-tool': FEATURES.AGENT_TOOLS,
|
|
52
51
|
};
|
|
53
52
|
export async function calculateComponentTemplateChoices(components, authType, distribution, accountId, projectMetadata) {
|
|
@@ -135,7 +134,7 @@ export async function v2ComponentFlow(platformVersion, projectBase, providedAuth
|
|
|
135
134
|
};
|
|
136
135
|
}
|
|
137
136
|
export function generateComponentPaths({ selectProjectTemplatePromptResponse, platformVersion, repoConfig, projectContents, authType, distribution, }) {
|
|
138
|
-
if (
|
|
137
|
+
if (isLegacyProject(platformVersion)) {
|
|
139
138
|
return [];
|
|
140
139
|
}
|
|
141
140
|
const components = selectProjectTemplatePromptResponse.componentTemplates?.map((componentTemplate) => {
|
package/lib/projects/delete.js
CHANGED
|
@@ -10,7 +10,7 @@ import { PromptExitError } from '../errors/PromptExitError.js';
|
|
|
10
10
|
import { EXIT_CODES } from '../enums/exitCodes.js';
|
|
11
11
|
import { AUTO_GENERATED_COMPONENT_TYPES } from '@hubspot/project-parsing-lib/constants';
|
|
12
12
|
import { mapToUserFacingType } from '@hubspot/project-parsing-lib/transform';
|
|
13
|
-
import {
|
|
13
|
+
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
14
14
|
import { COMPONENT_TYPES, SUBCOMPONENT_TYPES, } from '@hubspot/local-dev-lib/enums/build';
|
|
15
15
|
export const DELETION_POLL_TIMEOUT_MS = 5 * 60 * 1000;
|
|
16
16
|
export const DELETION_DEPLOY_SUCCESS_STATES = [
|
|
@@ -81,7 +81,7 @@ export async function checkDeployedComponents(accountId, projectName) {
|
|
|
81
81
|
if (!platformVersion) {
|
|
82
82
|
throw new Error(commands.project.delete.errors.noPlatformVersion);
|
|
83
83
|
}
|
|
84
|
-
if (
|
|
84
|
+
if (isLegacyProject(platformVersion)) {
|
|
85
85
|
const userVisibleComponents = [];
|
|
86
86
|
projectData.deployedBuild?.subbuildStatuses?.forEach(item => {
|
|
87
87
|
if (LEGACY_COMPONENTS_TO_FILTER.includes(item.buildType)) {
|
package/lib/projects/deploy.d.ts
CHANGED
|
@@ -10,4 +10,4 @@ export declare function logDeployErrors(errorData: {
|
|
|
10
10
|
};
|
|
11
11
|
}>;
|
|
12
12
|
}): void;
|
|
13
|
-
export declare function handleProjectDeploy(targetAccountId: number, projectName: string, buildId: number,
|
|
13
|
+
export declare function handleProjectDeploy(targetAccountId: number, projectName: string, buildId: number, isLegacyProject: boolean, force: boolean): Promise<Deploy | undefined>;
|
package/lib/projects/deploy.js
CHANGED
|
@@ -47,9 +47,9 @@ function handleBlockedDeploy(deployResp) {
|
|
|
47
47
|
uiLogger.log('');
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
-
export async function handleProjectDeploy(targetAccountId, projectName, buildId,
|
|
50
|
+
export async function handleProjectDeploy(targetAccountId, projectName, buildId, isLegacyProject, force) {
|
|
51
51
|
let deployId;
|
|
52
|
-
if (
|
|
52
|
+
if (!isLegacyProject) {
|
|
53
53
|
const { data: deployResp } = await deployProjectV2(targetAccountId, projectName, buildId, force);
|
|
54
54
|
if (!deployResp || deployResp.buildResultType !== 'DEPLOY_QUEUED') {
|
|
55
55
|
if (deployResp?.buildResultType === 'DEPLOY_BLOCKED') {
|
package/lib/projects/upload.js
CHANGED
|
@@ -6,16 +6,18 @@ import { uploadProject } from '@hubspot/local-dev-lib/api/projects';
|
|
|
6
6
|
import { shouldIgnoreFile } from '@hubspot/local-dev-lib/ignoreRules';
|
|
7
7
|
import { isTranslationError, translate, } from '@hubspot/project-parsing-lib/translate';
|
|
8
8
|
import { projectContainsHsMetaFiles } from '@hubspot/project-parsing-lib/projects';
|
|
9
|
+
import { findAndParsePackageJsonFiles, collectWorkspaceDirectories, collectFileDependencies, } from '@hubspot/project-parsing-lib/workspaces';
|
|
9
10
|
import SpinniesManager from '../ui/SpinniesManager.js';
|
|
10
11
|
import { uiAccountDescription } from '../ui/index.js';
|
|
11
12
|
import util from 'node:util';
|
|
12
13
|
import { lib } from '../../lang/en.js';
|
|
13
14
|
import { ensureProjectExists } from './ensureProjectExists.js';
|
|
14
15
|
import { uiLogger } from '../ui/logger.js';
|
|
15
|
-
import { isV2Project } from './platformVersion.js';
|
|
16
16
|
import ProjectValidationError from '../errors/ProjectValidationError.js';
|
|
17
17
|
import { walk } from '@hubspot/local-dev-lib/fs';
|
|
18
18
|
import { LEGACY_CONFIG_FILES } from '../constants.js';
|
|
19
|
+
import { archiveWorkspacesAndDependencies, getPackageJsonPathsToUpdate, getLockfilePathsToUpdate, } from './workspaces.js';
|
|
20
|
+
import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
|
|
19
21
|
async function uploadProjectFiles(accountId, projectName, filePath, uploadMessage, platformVersion, intermediateRepresentation) {
|
|
20
22
|
const accountIdentifier = uiAccountDescription(accountId) || `${accountId}`;
|
|
21
23
|
SpinniesManager.add('upload', {
|
|
@@ -48,6 +50,15 @@ export async function handleProjectUpload({ accountId, projectConfig, projectDir
|
|
|
48
50
|
await validateNoHSMetaMismatch(srcDir, projectConfig);
|
|
49
51
|
const tempFile = tmp.fileSync({ postfix: '.zip' });
|
|
50
52
|
uiLogger.debug(lib.projectUpload.handleProjectUpload.compressing(tempFile.name));
|
|
53
|
+
// Collect workspace directories and file: dependencies for v2+ projects only.
|
|
54
|
+
// Versions <= 2025.1 do not support the new npm workspaces bundling behavior.
|
|
55
|
+
let workspaceMappings = [];
|
|
56
|
+
let fileDependencyMappings = [];
|
|
57
|
+
if (!isLegacyProject(projectConfig.platformVersion)) {
|
|
58
|
+
const parsedPackageJsons = await findAndParsePackageJsonFiles(srcDir);
|
|
59
|
+
workspaceMappings = await collectWorkspaceDirectories(parsedPackageJsons);
|
|
60
|
+
fileDependencyMappings = await collectFileDependencies(parsedPackageJsons);
|
|
61
|
+
}
|
|
51
62
|
const output = fs.createWriteStream(tempFile.name);
|
|
52
63
|
const archive = archiver('zip');
|
|
53
64
|
const result = new Promise((resolve, reject) => output.on('close', async function () {
|
|
@@ -91,8 +102,14 @@ export async function handleProjectUpload({ accountId, projectConfig, projectDir
|
|
|
91
102
|
}
|
|
92
103
|
}));
|
|
93
104
|
archive.pipe(output);
|
|
105
|
+
const modifiedPackageJsonPaths = getPackageJsonPathsToUpdate(srcDir, workspaceMappings, fileDependencyMappings);
|
|
106
|
+
const lockfilePathsToUpdate = getLockfilePathsToUpdate(srcDir, workspaceMappings, fileDependencyMappings);
|
|
94
107
|
let loggedIgnoredNodeModule = false;
|
|
95
108
|
archive.directory(srcDir, false, file => {
|
|
109
|
+
if (modifiedPackageJsonPaths.has(file.name) ||
|
|
110
|
+
lockfilePathsToUpdate.has(file.name)) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
96
113
|
const ignored = shouldIgnoreFile(file.name, true);
|
|
97
114
|
if (ignored) {
|
|
98
115
|
const isNodeModule = file.name.includes('node_modules');
|
|
@@ -105,6 +122,8 @@ export async function handleProjectUpload({ accountId, projectConfig, projectDir
|
|
|
105
122
|
}
|
|
106
123
|
return ignored ? false : file;
|
|
107
124
|
});
|
|
125
|
+
// Archive workspaces and file: dependencies
|
|
126
|
+
await archiveWorkspacesAndDependencies(archive, srcDir, projectDir, workspaceMappings, fileDependencyMappings);
|
|
108
127
|
archive.finalize();
|
|
109
128
|
return result;
|
|
110
129
|
}
|
|
@@ -113,7 +132,7 @@ export async function validateSourceDirectory(srcDir, projectConfig, projectDir)
|
|
|
113
132
|
if (!projectFilePaths || projectFilePaths.length === 0) {
|
|
114
133
|
throw new ProjectValidationError(lib.projectUpload.handleProjectUpload.emptySource(projectConfig.srcDir));
|
|
115
134
|
}
|
|
116
|
-
if (
|
|
135
|
+
if (!isLegacyProject(projectConfig.platformVersion)) {
|
|
117
136
|
projectFilePaths.forEach(filePath => {
|
|
118
137
|
const filename = path.basename(filePath);
|
|
119
138
|
if (LEGACY_CONFIG_FILES.includes(filename)) {
|
|
@@ -124,7 +143,7 @@ export async function validateSourceDirectory(srcDir, projectConfig, projectDir)
|
|
|
124
143
|
}
|
|
125
144
|
export async function validateNoHSMetaMismatch(srcDir, projectConfig) {
|
|
126
145
|
const hasHsMetaFiles = await projectContainsHsMetaFiles(srcDir);
|
|
127
|
-
if (
|
|
146
|
+
if (isLegacyProject(projectConfig.platformVersion) && hasHsMetaFiles) {
|
|
128
147
|
throw new ProjectValidationError(lib.projectUpload.wrongPlatformVersionMetaFiles);
|
|
129
148
|
}
|
|
130
149
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import archiver from 'archiver';
|
|
2
|
+
import { WorkspaceMapping, FileDependencyMapping } from '@hubspot/project-parsing-lib/workspaces';
|
|
3
|
+
/**
|
|
4
|
+
* Result of archiving workspaces and file dependencies
|
|
5
|
+
*/
|
|
6
|
+
export type WorkspaceArchiveResult = {
|
|
7
|
+
packageWorkspaces: Map<string, string[]>;
|
|
8
|
+
packageFileDeps: Map<string, Map<string, string>>;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Generates a short hash of the input string for use in workspace paths.
|
|
12
|
+
* Uses SHA256 truncated to 8 hex characters (4 billion possibilities).
|
|
13
|
+
*/
|
|
14
|
+
export declare function shortHash(input: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Determines the archive path for an external workspace or file: dependency.
|
|
17
|
+
* Produces `_workspaces/<basename>-<hash>` with no subdirectory.
|
|
18
|
+
* The hash prevents collisions between different directories with the same basename.
|
|
19
|
+
*/
|
|
20
|
+
export declare function computeExternalArchivePath(absolutePath: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Updates package.json files in the archive to reflect new workspace and file: dependency paths.
|
|
23
|
+
*
|
|
24
|
+
* Workspace entries in packageWorkspaces are already in final form:
|
|
25
|
+
* - Internal workspaces: relative paths (e.g. "../packages/utils")
|
|
26
|
+
* - External workspaces: relative paths (e.g. "../_workspaces/logger-abc")
|
|
27
|
+
*
|
|
28
|
+
* Only external file: dependencies appear in packageFileDeps; internal ones
|
|
29
|
+
* keep their original file: references and are left untouched.
|
|
30
|
+
*/
|
|
31
|
+
export declare function updatePackageJsonInArchive(archive: archiver.Archiver, srcDir: string, packageWorkspaces: Map<string, string[]>, packageFileDeps: Map<string, Map<string, string>>): Promise<void>;
|
|
32
|
+
export declare function rewriteLockfileForExternalDeps(lockfileContent: Record<string, unknown>, pathMappings: Array<{
|
|
33
|
+
oldPath: string;
|
|
34
|
+
newPath: string;
|
|
35
|
+
}>): Record<string, unknown>;
|
|
36
|
+
export declare function getPackageJsonPathsToUpdate(srcDir: string, workspaceMappings: WorkspaceMapping[], fileDependencyMappings: FileDependencyMapping[]): Set<string>;
|
|
37
|
+
export declare function getLockfilePathsToUpdate(srcDir: string, workspaceMappings: WorkspaceMapping[], fileDependencyMappings: FileDependencyMapping[]): Set<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Main orchestration function that handles archiving of workspaces and file dependencies.
|
|
40
|
+
* This is the clean integration point for upload.ts.
|
|
41
|
+
*/
|
|
42
|
+
export declare function archiveWorkspacesAndDependencies(archive: archiver.Archiver, srcDir: string, projectDir: string, workspaceMappings: WorkspaceMapping[], fileDependencyMappings: FileDependencyMapping[]): Promise<WorkspaceArchiveResult>;
|