@hubspot/cli 7.7.35-experimental.0 → 7.8.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/bin/cli.js +31 -25
- package/commands/__tests__/auth.test.js +5 -0
- package/commands/__tests__/doctor.test.js +16 -16
- package/commands/__tests__/getStarted.test.js +2 -2
- package/commands/__tests__/mcp.test.js +1 -1
- package/commands/__tests__/project.test.js +2 -3
- package/commands/account/auth.js +1 -0
- package/commands/account/clean.js +18 -27
- package/commands/account/createOverride.js +13 -31
- package/commands/account/info.js +20 -31
- package/commands/account/list.js +16 -22
- package/commands/account/remove.js +12 -20
- package/commands/account/removeOverride.js +11 -21
- package/commands/account/rename.js +6 -9
- package/commands/account/use.js +12 -26
- package/commands/account.js +2 -2
- package/commands/app/__tests__/migrate.test.js +5 -6
- package/commands/app/migrate.js +13 -19
- package/commands/app/secret/add.js +2 -1
- package/commands/app/secret/delete.js +2 -1
- package/commands/app/secret/list.js +2 -1
- package/commands/app/secret/update.js +2 -1
- package/commands/app/secret.js +2 -1
- package/commands/app.js +2 -2
- package/commands/auth.d.ts +1 -0
- package/commands/auth.js +17 -7
- package/commands/cms/convertFields.js +7 -9
- package/commands/cms/getReactModule.js +9 -14
- package/commands/cms/lighthouseScore.js +33 -36
- package/commands/cms.js +2 -2
- package/commands/completion.js +3 -3
- package/commands/config/set.d.ts +1 -1
- package/commands/config/set.js +64 -37
- package/commands/config.js +2 -2
- package/commands/create.js +2 -2
- package/commands/customObject/create.js +10 -12
- package/commands/customObject/schema/create.js +9 -11
- package/commands/customObject/schema/delete.js +16 -16
- package/commands/customObject/schema/fetch-all.js +12 -11
- package/commands/customObject/schema/fetch.js +15 -15
- package/commands/customObject/schema/list.js +4 -4
- package/commands/customObject/schema/update.js +13 -13
- package/commands/customObject/schema.js +2 -2
- package/commands/customObject.js +6 -7
- package/commands/doctor.js +8 -11
- package/commands/feedback.js +8 -13
- package/commands/fetch.js +8 -8
- package/commands/filemanager/fetch.js +7 -7
- package/commands/filemanager/upload.js +15 -34
- package/commands/filemanager.js +2 -2
- package/commands/function/deploy.js +11 -29
- package/commands/function/list.js +8 -8
- package/commands/function/server.js +9 -11
- package/commands/function.d.ts +1 -1
- package/commands/function.js +2 -2
- package/commands/getStarted.d.ts +0 -2
- package/commands/getStarted.js +4 -4
- package/commands/hubdb/clear.js +7 -15
- package/commands/hubdb/create.js +9 -15
- package/commands/hubdb/delete.js +8 -15
- package/commands/hubdb/fetch.js +6 -9
- package/commands/hubdb.d.ts +1 -1
- package/commands/hubdb.js +2 -2
- package/commands/init.js +2 -3
- package/commands/lint.js +16 -16
- package/commands/list.js +8 -14
- package/commands/logs.js +14 -20
- package/commands/mcp/__tests__/setup.test.js +2 -2
- package/commands/mcp/setup.js +11 -2
- package/commands/mcp.js +3 -3
- package/commands/mv.js +6 -17
- package/commands/open.js +5 -5
- package/commands/project/__tests__/add.test.js +15 -13
- package/commands/project/__tests__/create.test.js +6 -6
- package/commands/project/__tests__/deploy.test.js +3 -7
- package/commands/project/__tests__/devUnifiedFlow.test.js +2 -4
- package/commands/project/__tests__/installDeps.test.js +8 -8
- package/commands/project/__tests__/list.test.js +31 -0
- package/commands/project/__tests__/logs.test.js +1 -4
- package/commands/project/__tests__/migrate.test.js +7 -7
- package/commands/project/__tests__/migrateApp.test.js +3 -7
- package/commands/project/__tests__/profile.test.js +1 -1
- package/commands/project/__tests__/validate.test.js +98 -0
- package/commands/project/add.d.ts +2 -2
- package/commands/project/add.js +7 -10
- package/commands/project/cloneApp.js +14 -19
- package/commands/project/create.js +3 -10
- package/commands/project/deploy.js +5 -5
- package/commands/project/dev/deprecatedFlow.js +9 -18
- package/commands/project/dev/index.js +21 -18
- package/commands/project/dev/unifiedFlow.js +14 -7
- package/commands/project/download.js +15 -16
- package/commands/project/installDeps.d.ts +2 -2
- package/commands/project/installDeps.js +9 -9
- package/commands/project/list.d.ts +4 -0
- package/commands/project/list.js +62 -0
- package/commands/project/listBuilds.js +12 -21
- package/commands/project/logs.js +21 -24
- package/commands/project/migrate.js +46 -15
- package/commands/project/migrateApp.js +10 -17
- package/commands/project/open.js +6 -14
- package/commands/project/profile/add.js +3 -3
- package/commands/project/profile/delete.js +1 -2
- package/commands/project/profile.js +2 -3
- package/commands/project/upload.js +16 -25
- package/commands/project/validate.js +7 -7
- package/commands/project/watch.js +13 -22
- package/commands/project.js +4 -3
- package/commands/sandbox/__tests__/create.test.js +5 -5
- package/commands/sandbox/create.js +22 -32
- package/commands/sandbox/delete.js +39 -64
- package/commands/sandbox.js +2 -2
- package/commands/secret/addSecret.js +7 -17
- package/commands/secret/deleteSecret.js +10 -20
- package/commands/secret/listSecret.js +8 -10
- package/commands/secret/updateSecret.js +9 -17
- package/commands/secret.js +2 -2
- package/commands/testAccount/__tests__/delete.test.js +2 -4
- package/commands/testAccount/create.js +2 -2
- package/commands/testAccount/delete.d.ts +4 -3
- package/commands/testAccount/delete.js +155 -14
- package/commands/testAccount/importData.d.ts +1 -1
- package/commands/testAccount/importData.js +1 -1
- package/commands/testAccount.js +1 -1
- package/commands/theme/preview.js +1 -4
- package/lang/en.d.ts +364 -110
- package/lang/en.js +409 -158
- package/lang/en.lyaml +4 -4
- package/lib/__tests__/buildAccount.test.js +4 -3
- package/lib/__tests__/commonOpts.test.js +1 -1
- package/lib/__tests__/dependencyManagement.test.js +1 -1
- package/lib/__tests__/developerTestAccounts.test.js +3 -3
- package/lib/__tests__/npm.test.js +1 -1
- package/lib/__tests__/oauth.test.js +4 -4
- package/lib/__tests__/process.test.js +10 -5
- package/lib/__tests__/sandboxSync.test.js +8 -8
- package/lib/__tests__/sandboxes.test.js +8 -8
- package/lib/__tests__/serverlessLogs.test.js +1 -1
- package/lib/__tests__/usageTracking.test.js +5 -5
- package/lib/__tests__/validation.test.js +2 -1
- package/lib/__tests__/yargsUtils.test.js +83 -9
- package/lib/app/__tests__/migrate.test.js +19 -56
- package/lib/app/__tests__/migrate_legacy.test.js +1 -1
- package/lib/app/migrate.d.ts +2 -8
- package/lib/app/migrate.js +6 -81
- package/lib/app/migrate_legacy.js +20 -24
- package/lib/buildAccount.d.ts +2 -2
- package/lib/buildAccount.js +32 -64
- package/lib/commonOpts.d.ts +1 -1
- package/lib/commonOpts.js +25 -22
- package/lib/configMigrate.js +88 -9
- package/lib/configOptions.js +7 -0
- package/lib/constants.d.ts +21 -1
- package/lib/constants.js +25 -1
- package/lib/dependencyManagement.js +9 -27
- package/lib/developerTestAccounts.js +9 -23
- package/lib/doctor/Diagnosis.js +11 -23
- package/lib/doctor/DiagnosticInfoBuilder.js +12 -11
- package/lib/doctor/Doctor.js +42 -90
- package/lib/doctor/__tests__/Doctor.test.js +4 -4
- package/lib/errorHandlers/index.js +12 -20
- package/lib/errorHandlers/suppressError.js +11 -18
- package/lib/lang.js +6 -5
- package/lib/links.d.ts +1 -0
- package/lib/links.js +14 -7
- package/lib/mcp/setup.js +1 -1
- package/lib/middleware/__test__/commandTargetingUtils.test.js +99 -0
- package/lib/middleware/__test__/configMiddleware.test.js +11 -11
- package/lib/middleware/__test__/yargsChecksMiddleware.test.js +6 -8
- package/lib/middleware/commandTargetingUtils.d.ts +8 -0
- package/lib/middleware/commandTargetingUtils.js +74 -0
- package/lib/middleware/configMiddleware.d.ts +1 -1
- package/lib/middleware/configMiddleware.js +21 -81
- package/lib/middleware/fireAlarmMiddleware.js +15 -5
- package/lib/middleware/gitMiddleware.js +5 -1
- package/lib/middleware/notificationsMiddleware.js +5 -11
- package/lib/middleware/yargsChecksMiddleware.js +6 -9
- package/lib/npm.js +2 -2
- package/lib/oauth.js +5 -5
- package/lib/process.js +5 -4
- package/lib/projects/__tests__/AppDevModeInterface.test.js +87 -90
- package/lib/projects/__tests__/LocalDevProcess.test.js +231 -19
- package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +89 -63
- package/lib/projects/__tests__/deploy.test.js +73 -8
- package/lib/projects/__tests__/localDevProjectHelpers.test.js +6 -2
- package/lib/projects/__tests__/platformVersion.test.js +8 -8
- package/lib/projects/__tests__/projects.test.js +12 -12
- package/lib/projects/__tests__/structure.test.js +3 -3
- package/lib/projects/__tests__/upload.test.d.ts +1 -0
- package/lib/projects/__tests__/upload.test.js +82 -0
- package/lib/projects/add/__tests__/legacyAddComponent.test.js +6 -6
- package/lib/projects/add/__tests__/v2AddComponent.test.d.ts +1 -0
- package/lib/projects/add/__tests__/{v3AddComponent.test.js → v2AddComponent.test.js} +39 -39
- package/lib/projects/add/{v3AddComponent.d.ts → v2AddComponent.d.ts} +1 -1
- package/lib/projects/add/{v3AddComponent.js → v2AddComponent.js} +5 -5
- package/lib/projects/create/__tests__/legacy.test.js +5 -5
- package/lib/projects/create/__tests__/v2.test.d.ts +1 -0
- package/lib/projects/create/__tests__/{v3.test.js → v2.test.js} +82 -7
- package/lib/projects/create/index.js +4 -4
- package/lib/projects/create/legacy.js +2 -2
- package/lib/projects/create/{v3.d.ts → v2.d.ts} +3 -3
- package/lib/projects/create/{v3.js → v2.js} +13 -11
- package/lib/projects/deploy.d.ts +1 -1
- package/lib/projects/deploy.js +2 -2
- package/lib/projects/localDev/AppDevModeInterface.d.ts +10 -1
- package/lib/projects/localDev/AppDevModeInterface.js +118 -89
- package/lib/projects/localDev/DevServerManager.d.ts +11 -29
- package/lib/projects/localDev/DevServerManager.js +19 -61
- package/lib/projects/localDev/DevServerManager_DEPRECATED.d.ts +40 -0
- package/lib/projects/localDev/DevServerManager_DEPRECATED.js +120 -0
- package/lib/projects/localDev/LocalDevLogger.d.ts +4 -0
- package/lib/projects/localDev/LocalDevLogger.js +27 -6
- package/lib/projects/localDev/{LocalDevManager.js → LocalDevManager_DEPRECATED.js} +10 -11
- package/lib/projects/localDev/LocalDevProcess.d.ts +7 -5
- package/lib/projects/localDev/LocalDevProcess.js +93 -21
- package/lib/projects/localDev/LocalDevState.d.ts +12 -8
- package/lib/projects/localDev/LocalDevState.js +27 -17
- package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +6 -1
- package/lib/projects/localDev/LocalDevWebsocketServer.js +94 -33
- package/lib/projects/localDev/helpers/account.d.ts +1 -1
- package/lib/projects/localDev/helpers/account.js +2 -2
- package/lib/projects/localDev/helpers/project.d.ts +1 -0
- package/lib/projects/localDev/helpers/project.js +44 -4
- package/lib/projects/localDev/localDevWebsocketServerUtils.d.ts +7 -0
- package/lib/projects/localDev/localDevWebsocketServerUtils.js +19 -0
- package/lib/projects/platformVersion.d.ts +1 -1
- package/lib/projects/platformVersion.js +1 -1
- package/lib/projects/pollProjectBuildAndDeploy.js +4 -4
- package/lib/projects/structure.js +6 -6
- package/lib/projects/upload.d.ts +1 -1
- package/lib/projects/upload.js +17 -8
- package/lib/projects/urls.d.ts +0 -1
- package/lib/projects/urls.js +0 -3
- package/lib/prompts/__tests__/downloadProjectPrompt.test.js +1 -0
- package/lib/prompts/__tests__/projectAddPrompt.test.js +10 -10
- package/lib/prompts/accountNamePrompt.js +14 -19
- package/lib/prompts/accountsPrompt.js +2 -2
- package/lib/prompts/cmsFieldPrompt.js +2 -2
- package/lib/prompts/createApiSamplePrompt.js +5 -5
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +10 -1
- package/lib/prompts/createFunctionPrompt.js +14 -14
- package/lib/prompts/createModulePrompt.js +9 -9
- package/lib/prompts/createTemplatePrompt.js +2 -2
- package/lib/prompts/downloadProjectPrompt.js +5 -8
- package/lib/prompts/installAppPrompt.d.ts +1 -6
- package/lib/prompts/installAppPrompt.js +1 -6
- package/lib/prompts/personalAccessKeyPrompt.js +3 -3
- package/lib/prompts/previewPrompt.js +6 -6
- package/lib/prompts/projectAddPrompt.d.ts +2 -2
- package/lib/prompts/projectAddPrompt.js +9 -2
- package/lib/prompts/projectDevTargetAccountPrompt.js +20 -32
- package/lib/prompts/projectNamePrompt.js +4 -8
- package/lib/prompts/projectsLogsPrompt.js +2 -4
- package/lib/prompts/promptUtils.js +30 -9
- package/lib/prompts/sandboxesPrompt.js +7 -7
- package/lib/prompts/secretPrompt.js +3 -3
- package/lib/prompts/selectAppPrompt.js +3 -3
- package/lib/prompts/selectHubDBTablePrompt.js +9 -13
- package/lib/prompts/selectProjectTemplatePrompt.js +2 -0
- package/lib/prompts/selectPublicAppForMigrationPrompt.js +15 -19
- package/lib/prompts/setAsDefaultAccountPrompt.js +4 -8
- package/lib/prompts/uploadPrompt.js +5 -5
- package/lib/sandboxSync.js +24 -41
- package/lib/sandboxes.js +19 -47
- package/lib/schema.js +3 -3
- package/lib/serverlessLogs.js +11 -13
- package/lib/theme/__tests__/migrate.test.d.ts +1 -0
- package/lib/theme/__tests__/migrate.test.js +233 -0
- package/lib/theme/migrate.d.ts +13 -0
- package/lib/theme/migrate.js +90 -0
- package/lib/ui/SpinniesManager.d.ts +2 -0
- package/lib/ui/SpinniesManager.js +7 -0
- package/lib/ui/boxen.js +1 -2
- package/lib/ui/git.js +13 -10
- package/lib/ui/index.d.ts +4 -0
- package/lib/ui/index.js +47 -38
- package/lib/ui/serverlessFunctionLogs.js +9 -7
- package/lib/ui/uiMessages.d.ts +72 -0
- package/lib/ui/uiMessages.js +75 -0
- package/lib/usageTracking.js +8 -8
- package/lib/validation.js +20 -23
- package/lib/yargsUtils.d.ts +1 -1
- package/lib/yargsUtils.js +12 -5
- package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +2 -2
- package/mcp-server/tools/index.js +4 -0
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +2 -2
- package/mcp-server/tools/project/CreateProjectTool.d.ts +2 -2
- package/mcp-server/tools/project/DocsSearchTool.d.ts +4 -1
- package/mcp-server/tools/project/DocsSearchTool.js +5 -5
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +23 -0
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +68 -0
- package/mcp-server/tools/project/GetApplicationInfoTool.d.ts +11 -0
- package/mcp-server/tools/project/GetApplicationInfoTool.js +49 -0
- package/mcp-server/tools/project/GetConfigValuesTool.d.ts +4 -1
- package/mcp-server/tools/project/GetConfigValuesTool.js +12 -6
- package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +2 -2
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +12 -10
- package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +169 -0
- package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +115 -0
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +8 -7
- package/mcp-server/utils/__tests__/cliConfig.test.d.ts +1 -0
- package/mcp-server/utils/__tests__/cliConfig.test.js +110 -0
- package/mcp-server/utils/cliConfig.d.ts +1 -0
- package/mcp-server/utils/cliConfig.js +12 -0
- package/mcp-server/utils/toolUsageTracking.js +2 -2
- package/package.json +8 -7
- package/types/LocalDev.d.ts +19 -3
- package/ui/index.js +1 -1
- package/lib/middleware/__test__/utils.test.js +0 -51
- package/lib/middleware/utils.d.ts +0 -8
- package/lib/middleware/utils.js +0 -14
- package/lib/projects/localDev/DevServerManagerV2.d.ts +0 -22
- package/lib/projects/localDev/DevServerManagerV2.js +0 -81
- /package/{lib/middleware/__test__/utils.test.d.ts → commands/project/__tests__/list.test.d.ts} +0 -0
- /package/{lib/projects/add/__tests__/v3AddComponent.test.d.ts → commands/project/__tests__/validate.test.d.ts} +0 -0
- /package/lib/{projects/create/__tests__/v3.test.d.ts → middleware/__test__/commandTargetingUtils.test.d.ts} +0 -0
- /package/lib/projects/localDev/{LocalDevManager.d.ts → LocalDevManager_DEPRECATED.d.ts} +0 -0
|
@@ -3,17 +3,22 @@ declare class LocalDevWebsocketServer {
|
|
|
3
3
|
private server?;
|
|
4
4
|
private debug?;
|
|
5
5
|
private localDevProcess;
|
|
6
|
-
private ALLOWED_ORIGINS;
|
|
7
6
|
constructor(localDevProcess: LocalDevProcess, debug?: boolean);
|
|
8
7
|
private log;
|
|
9
8
|
private logError;
|
|
10
9
|
private sendMessage;
|
|
11
10
|
private handleUpload;
|
|
11
|
+
private handleDeploy;
|
|
12
|
+
private handleAppInstallSuccess;
|
|
13
|
+
private handleAppInstallFailure;
|
|
14
|
+
private handleAppInstallInitiated;
|
|
12
15
|
private setupMessageHandlers;
|
|
16
|
+
private sendCliMetadata;
|
|
13
17
|
private sendProjectData;
|
|
14
18
|
private setupProjectNodesListener;
|
|
15
19
|
private setupAppDataListener;
|
|
16
20
|
private setupUploadWarningsListener;
|
|
21
|
+
private setupDevServersStartedListener;
|
|
17
22
|
private setupStateListeners;
|
|
18
23
|
start(): Promise<void>;
|
|
19
24
|
shutdown(): void;
|
|
@@ -1,51 +1,75 @@
|
|
|
1
1
|
import { WebSocketServer } from 'ws';
|
|
2
2
|
import { isPortManagerServerRunning, requestPorts, } from '@hubspot/local-dev-lib/portManager';
|
|
3
|
-
import {
|
|
3
|
+
import { uiLogger } from '../../ui/logger.js';
|
|
4
4
|
import { addLocalStateFlag } from '@hubspot/local-dev-lib/config';
|
|
5
|
-
import { LOCAL_DEV_UI_MESSAGE_SEND_TYPES,
|
|
5
|
+
import { LOCAL_DEV_UI_MESSAGE_SEND_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES, CONFIG_LOCAL_STATE_FLAGS, } from '../../constants.js';
|
|
6
6
|
import { lib } from '../../../lang/en.js';
|
|
7
7
|
import { removeAnsiCodes } from '../../ui/removeAnsiCodes.js';
|
|
8
|
+
import { isDeployWebsocketMessage, isViewedWelcomeScreenWebsocketMessage, isUploadWebsocketMessage, isAppInstallFailureWebsocketMessage, isAppInstallSuccessWebsocketMessage, isAppInstallInitiatedWebsocketMessage, } from './localDevWebsocketServerUtils.js';
|
|
9
|
+
import pkg from '../../../package.json' with { type: 'json' };
|
|
8
10
|
const SERVER_INSTANCE_ID = 'local-dev-ui-websocket-server';
|
|
11
|
+
const LOCAL_DEV_WEBSOCKET_SERVER_VERSION = 2;
|
|
9
12
|
const LOG_PREFIX = '[LocalDevWebsocketServer]';
|
|
13
|
+
const DOMAINS = ['hubspot.com', 'hubspotqa.com'];
|
|
14
|
+
const SUBDOMAINS = ['local', 'app', 'app-na2', 'app-na3', 'app-ap1', 'app-eu1'];
|
|
15
|
+
const ALLOWED_ORIGIN_REGEX = new RegExp(`^https://(${SUBDOMAINS.join('|')})\\.(${DOMAINS.join('|')})$`);
|
|
10
16
|
class LocalDevWebsocketServer {
|
|
11
17
|
server;
|
|
12
18
|
debug;
|
|
13
19
|
localDevProcess;
|
|
14
|
-
ALLOWED_ORIGINS = [
|
|
15
|
-
'https://app.hubspot.com',
|
|
16
|
-
'https://app.hubspotqa.com',
|
|
17
|
-
'https://local.hubspot.com',
|
|
18
|
-
'https://local.hubspotqa.com',
|
|
19
|
-
];
|
|
20
20
|
constructor(localDevProcess, debug) {
|
|
21
21
|
this.localDevProcess = localDevProcess;
|
|
22
22
|
this.debug = debug;
|
|
23
23
|
}
|
|
24
24
|
log(message) {
|
|
25
25
|
if (this.debug) {
|
|
26
|
-
|
|
26
|
+
uiLogger.log(`${LOG_PREFIX} ${message}`);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
logError(message) {
|
|
30
30
|
if (this.debug) {
|
|
31
|
-
|
|
31
|
+
uiLogger.error(`${LOG_PREFIX} ${message}`);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
sendMessage(websocket, message) {
|
|
35
35
|
websocket.send(JSON.stringify(message));
|
|
36
36
|
}
|
|
37
37
|
async handleUpload(websocket) {
|
|
38
|
-
const uploadSuccess = await this.localDevProcess.uploadProject();
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
38
|
+
const { uploadSuccess, buildSuccess, deploySuccess, deployId } = await this.localDevProcess.uploadProject();
|
|
39
|
+
this.sendMessage(websocket, {
|
|
40
|
+
type: uploadSuccess
|
|
41
|
+
? LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_SUCCESS
|
|
42
|
+
: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPLOAD_FAILURE,
|
|
43
|
+
data: {
|
|
44
|
+
latestBuild: this.localDevProcess.projectData.latestBuild,
|
|
45
|
+
deployedBuild: this.localDevProcess.projectData.deployedBuild,
|
|
46
|
+
buildSuccess,
|
|
47
|
+
deploySuccess,
|
|
48
|
+
deployId,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async handleDeploy(websocket, force) {
|
|
53
|
+
const { success, deployId } = await this.localDevProcess.deployLatestBuild(force);
|
|
54
|
+
this.sendMessage(websocket, {
|
|
55
|
+
type: success
|
|
56
|
+
? LOCAL_DEV_UI_MESSAGE_SEND_TYPES.DEPLOY_SUCCESS
|
|
57
|
+
: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.DEPLOY_FAILURE,
|
|
58
|
+
data: {
|
|
59
|
+
latestBuild: this.localDevProcess.projectData.latestBuild,
|
|
60
|
+
deployedBuild: this.localDevProcess.projectData.deployedBuild,
|
|
61
|
+
latestDeployId: deployId,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async handleAppInstallSuccess() {
|
|
66
|
+
this.localDevProcess.sendDevServerMessage(LOCAL_DEV_SERVER_MESSAGE_TYPES.STATIC_AUTH_APP_INSTALL_SUCCESS);
|
|
67
|
+
}
|
|
68
|
+
async handleAppInstallFailure() {
|
|
69
|
+
this.localDevProcess.sendDevServerMessage(LOCAL_DEV_SERVER_MESSAGE_TYPES.STATIC_AUTH_APP_INSTALL_FAILURE);
|
|
70
|
+
}
|
|
71
|
+
async handleAppInstallInitiated() {
|
|
72
|
+
this.localDevProcess.sendDevServerMessage(LOCAL_DEV_SERVER_MESSAGE_TYPES.OAUTH_APP_INSTALL_INITIATED);
|
|
49
73
|
}
|
|
50
74
|
setupMessageHandlers(websocket) {
|
|
51
75
|
websocket.on('message', data => {
|
|
@@ -55,15 +79,26 @@ class LocalDevWebsocketServer {
|
|
|
55
79
|
this.logError(lib.LocalDevWebsocketServer.errors.missingTypeField(data.toString()));
|
|
56
80
|
return;
|
|
57
81
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
82
|
+
if (isUploadWebsocketMessage(message)) {
|
|
83
|
+
this.handleUpload(websocket);
|
|
84
|
+
}
|
|
85
|
+
else if (isDeployWebsocketMessage(message)) {
|
|
86
|
+
this.handleDeploy(websocket, message.data.force);
|
|
87
|
+
}
|
|
88
|
+
else if (isViewedWelcomeScreenWebsocketMessage(message)) {
|
|
89
|
+
addLocalStateFlag(CONFIG_LOCAL_STATE_FLAGS.LOCAL_DEV_UI_WELCOME);
|
|
90
|
+
}
|
|
91
|
+
else if (isAppInstallSuccessWebsocketMessage(message)) {
|
|
92
|
+
this.handleAppInstallSuccess();
|
|
93
|
+
}
|
|
94
|
+
else if (isAppInstallFailureWebsocketMessage(message)) {
|
|
95
|
+
this.handleAppInstallFailure();
|
|
96
|
+
}
|
|
97
|
+
else if (isAppInstallInitiatedWebsocketMessage(message)) {
|
|
98
|
+
this.handleAppInstallInitiated();
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.logError(lib.LocalDevWebsocketServer.errors.unknownMessageType(message.type));
|
|
67
102
|
}
|
|
68
103
|
}
|
|
69
104
|
catch (e) {
|
|
@@ -71,12 +106,23 @@ class LocalDevWebsocketServer {
|
|
|
71
106
|
}
|
|
72
107
|
});
|
|
73
108
|
}
|
|
109
|
+
sendCliMetadata(websocket) {
|
|
110
|
+
this.sendMessage(websocket, {
|
|
111
|
+
type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.CLI_METADATA,
|
|
112
|
+
data: {
|
|
113
|
+
cliVersion: pkg.version,
|
|
114
|
+
localDevWebsocketServerVersion: LOCAL_DEV_WEBSOCKET_SERVER_VERSION,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
74
118
|
sendProjectData(websocket) {
|
|
75
119
|
this.sendMessage(websocket, {
|
|
76
120
|
type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.UPDATE_PROJECT_DATA,
|
|
77
121
|
data: {
|
|
78
|
-
projectName: this.localDevProcess.
|
|
79
|
-
projectId: this.localDevProcess.
|
|
122
|
+
projectName: this.localDevProcess.projectData.name,
|
|
123
|
+
projectId: this.localDevProcess.projectData.id,
|
|
124
|
+
latestBuild: this.localDevProcess.projectData.latestBuild,
|
|
125
|
+
deployedBuild: this.localDevProcess.projectData.deployedBuild,
|
|
80
126
|
targetProjectAccountId: this.localDevProcess.targetProjectAccountId,
|
|
81
127
|
targetTestingAccountId: this.localDevProcess.targetTestingAccountId,
|
|
82
128
|
},
|
|
@@ -119,10 +165,24 @@ class LocalDevWebsocketServer {
|
|
|
119
165
|
this.localDevProcess.removeStateListener('uploadWarnings', listener);
|
|
120
166
|
});
|
|
121
167
|
}
|
|
168
|
+
setupDevServersStartedListener(websocket) {
|
|
169
|
+
const listener = (devServersStarted) => {
|
|
170
|
+
if (devServersStarted) {
|
|
171
|
+
this.sendMessage(websocket, {
|
|
172
|
+
type: LOCAL_DEV_UI_MESSAGE_SEND_TYPES.DEV_SERVERS_STARTED,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
this.localDevProcess.addStateListener('devServersStarted', listener);
|
|
177
|
+
websocket.on('close', () => {
|
|
178
|
+
this.localDevProcess.removeStateListener('devServersStarted', listener);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
122
181
|
setupStateListeners(websocket) {
|
|
123
182
|
this.setupProjectNodesListener(websocket);
|
|
124
183
|
this.setupAppDataListener(websocket);
|
|
125
184
|
this.setupUploadWarningsListener(websocket);
|
|
185
|
+
this.setupDevServersStartedListener(websocket);
|
|
126
186
|
}
|
|
127
187
|
async start() {
|
|
128
188
|
const portManagerIsRunning = await isPortManagerServerRunning();
|
|
@@ -135,10 +195,11 @@ class LocalDevWebsocketServer {
|
|
|
135
195
|
this.log(lib.LocalDevWebsocketServer.logs.startup(port));
|
|
136
196
|
this.server.on('connection', (ws, req) => {
|
|
137
197
|
const origin = req.headers.origin;
|
|
138
|
-
if (!origin || !
|
|
198
|
+
if (!origin || !ALLOWED_ORIGIN_REGEX.test(origin)) {
|
|
139
199
|
ws.close(1008, lib.LocalDevWebsocketServer.errors.originNotAllowed(origin));
|
|
140
200
|
return;
|
|
141
201
|
}
|
|
202
|
+
this.sendCliMetadata(ws);
|
|
142
203
|
this.sendProjectData(ws);
|
|
143
204
|
this.setupMessageHandlers(ws);
|
|
144
205
|
this.setupStateListeners(ws);
|
|
@@ -8,7 +8,7 @@ export declare function checkIfParentAccountIsAuthed(accountConfig: CLIAccount):
|
|
|
8
8
|
export declare function checkIfAccountFlagIsSupported(accountConfig: CLIAccount, hasPublicApps: boolean): void;
|
|
9
9
|
export declare function suggestRecommendedNestedAccount(accounts: CLIAccount[], accountConfig: CLIAccount, hasPublicApps: boolean): Promise<ProjectDevTargetAccountPromptResponse>;
|
|
10
10
|
export declare function createSandboxForLocalDev(accountId: number, accountConfig: CLIAccount, env: Environment): Promise<number>;
|
|
11
|
-
export declare function createDeveloperTestAccountForLocalDev(accountId: number, accountConfig: CLIAccount, env: Environment,
|
|
11
|
+
export declare function createDeveloperTestAccountForLocalDev(accountId: number, accountConfig: CLIAccount, env: Environment, useV2?: boolean): Promise<number>;
|
|
12
12
|
export declare function useExistingDevTestAccount(env: Environment, account: DeveloperTestAccount): Promise<void>;
|
|
13
13
|
export declare function hasSandboxes(account: CLIAccount): Promise<boolean>;
|
|
14
14
|
export declare function selectAccountTypePrompt(accountConfig: CLIAccount): Promise<string | null>;
|
|
@@ -138,7 +138,7 @@ export async function createSandboxForLocalDev(accountId, accountConfig, env) {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
// Create a developer test account and return its accountId
|
|
141
|
-
export async function createDeveloperTestAccountForLocalDev(accountId, accountConfig, env,
|
|
141
|
+
export async function createDeveloperTestAccountForLocalDev(accountId, accountConfig, env, useV2 = false) {
|
|
142
142
|
let currentPortalCount = 0;
|
|
143
143
|
let maxTestPortals = 10;
|
|
144
144
|
try {
|
|
@@ -168,7 +168,7 @@ export async function createDeveloperTestAccountForLocalDev(accountId, accountCo
|
|
|
168
168
|
accountType: HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST,
|
|
169
169
|
});
|
|
170
170
|
trackCommandMetadataUsage('developer-test-account-create', { step: 'project-dev' }, accountId);
|
|
171
|
-
const result = await buildDeveloperTestAccount(name, accountConfig, env, maxTestPortals,
|
|
171
|
+
const result = await buildDeveloperTestAccount(name, accountConfig, env, maxTestPortals, useV2);
|
|
172
172
|
return result;
|
|
173
173
|
}
|
|
174
174
|
catch (err) {
|
|
@@ -10,3 +10,4 @@ export declare function compareLocalProjectToDeployed(projectConfig: ProjectConf
|
|
|
10
10
|
export declare function isDeployedProjectUpToDateWithLocal(projectConfig: ProjectConfig, accountId: number, deployedBuildId: number, localProjectNodes: {
|
|
11
11
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
12
12
|
}, profile?: string): Promise<boolean>;
|
|
13
|
+
export declare function checkAndInstallDependencies(): Promise<void>;
|
|
@@ -18,8 +18,9 @@ import SpinniesManager from '../../../ui/SpinniesManager.js';
|
|
|
18
18
|
import { EXIT_CODES } from '../../../enums/exitCodes.js';
|
|
19
19
|
import { handleProjectUpload } from '../../upload.js';
|
|
20
20
|
import { pollProjectBuildAndDeploy } from '../../pollProjectBuildAndDeploy.js';
|
|
21
|
-
import { logError } from '../../../errorHandlers/index.js';
|
|
21
|
+
import { debugError, logError } from '../../../errorHandlers/index.js';
|
|
22
22
|
import { ApiErrorContext } from '../../../errorHandlers/index.js';
|
|
23
|
+
import { getProjectPackageJsonLocations, hasMissingPackages, installPackages, } from '../../../dependencyManagement.js';
|
|
23
24
|
// Prompt the user to create a new project if one doesn't exist on their target account
|
|
24
25
|
export async function createNewProjectForLocalDev(projectConfig, targetAccountId, shouldCreateWithoutConfirmation, hasPublicApps) {
|
|
25
26
|
// Create the project without prompting if this is a newly created sandbox
|
|
@@ -153,9 +154,8 @@ export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountI
|
|
|
153
154
|
try {
|
|
154
155
|
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'hubspot-project-compare-'));
|
|
155
156
|
const { data: zippedProject } = await downloadProject(accountId, projectConfig.name, deployedBuildId);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const deployedProjectSourceDir = path.join(extractedProjectPath, projectConfig.srcDir);
|
|
157
|
+
await extractZipArchive(zippedProject, sanitizeFileName(projectConfig.name), tempDir, { hideLogs: true });
|
|
158
|
+
const deployedProjectSourceDir = path.join(tempDir, projectConfig.srcDir);
|
|
159
159
|
const { intermediateNodesIndexedByUid: deployedProjectNodes } = await translate({
|
|
160
160
|
projectSourceDir: deployedProjectSourceDir,
|
|
161
161
|
platformVersion: projectConfig.platformVersion,
|
|
@@ -163,6 +163,10 @@ export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountI
|
|
|
163
163
|
}, { profile });
|
|
164
164
|
return isDeepEqual(localProjectNodes, deployedProjectNodes, ['localDev']);
|
|
165
165
|
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
debugError(err);
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
166
170
|
finally {
|
|
167
171
|
// Clean up temporary directory
|
|
168
172
|
if (tempDir && (await fs.pathExists(tempDir))) {
|
|
@@ -170,3 +174,39 @@ export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountI
|
|
|
170
174
|
}
|
|
171
175
|
}
|
|
172
176
|
}
|
|
177
|
+
export async function checkAndInstallDependencies() {
|
|
178
|
+
SpinniesManager.init();
|
|
179
|
+
uiLogger.log('');
|
|
180
|
+
SpinniesManager.add('checkingDependencies', {
|
|
181
|
+
text: lib.localDevHelpers.project.checkAndInstallDependencies
|
|
182
|
+
.checkingDependencies,
|
|
183
|
+
});
|
|
184
|
+
try {
|
|
185
|
+
const installLocations = await getProjectPackageJsonLocations();
|
|
186
|
+
const locationsToInstall = [];
|
|
187
|
+
for (const location of installLocations) {
|
|
188
|
+
if (await hasMissingPackages(location)) {
|
|
189
|
+
locationsToInstall.push(location);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (locationsToInstall.length > 0) {
|
|
193
|
+
SpinniesManager.remove('checkingDependencies');
|
|
194
|
+
await installPackages({ installLocations: locationsToInstall });
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
SpinniesManager.succeed('checkingDependencies', {
|
|
198
|
+
text: lib.localDevHelpers.project.checkAndInstallDependencies
|
|
199
|
+
.dependenciesUpToDate,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
uiLogger.log('');
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
logError(e);
|
|
206
|
+
SpinniesManager.fail('checkingDependencies', {
|
|
207
|
+
text: lib.localDevHelpers.project.checkAndInstallDependencies
|
|
208
|
+
.dependenciesFailure,
|
|
209
|
+
});
|
|
210
|
+
process.exit(EXIT_CODES.ERROR);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { LocalDevDeployWebsocketMessage, LocalDevWebsocketMessage } from '../../../types/LocalDev.js';
|
|
2
|
+
export declare function isUploadWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
|
|
3
|
+
export declare function isDeployWebsocketMessage(message: LocalDevWebsocketMessage): message is LocalDevDeployWebsocketMessage;
|
|
4
|
+
export declare function isViewedWelcomeScreenWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
|
|
5
|
+
export declare function isAppInstallSuccessWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
|
|
6
|
+
export declare function isAppInstallInitiatedWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
|
|
7
|
+
export declare function isAppInstallFailureWebsocketMessage(message: LocalDevWebsocketMessage): boolean;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES } from '../../constants.js';
|
|
2
|
+
export function isUploadWebsocketMessage(message) {
|
|
3
|
+
return message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.UPLOAD;
|
|
4
|
+
}
|
|
5
|
+
export function isDeployWebsocketMessage(message) {
|
|
6
|
+
return message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.DEPLOY;
|
|
7
|
+
}
|
|
8
|
+
export function isViewedWelcomeScreenWebsocketMessage(message) {
|
|
9
|
+
return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.VIEWED_WELCOME_SCREEN);
|
|
10
|
+
}
|
|
11
|
+
export function isAppInstallSuccessWebsocketMessage(message) {
|
|
12
|
+
return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.APP_INSTALL_SUCCESS);
|
|
13
|
+
}
|
|
14
|
+
export function isAppInstallInitiatedWebsocketMessage(message) {
|
|
15
|
+
return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.APP_INSTALL_INITIATED);
|
|
16
|
+
}
|
|
17
|
+
export function isAppInstallFailureWebsocketMessage(message) {
|
|
18
|
+
return (message.type === LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES.APP_INSTALL_FAILURE);
|
|
19
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function
|
|
1
|
+
export declare function isV2Project(platformVersion?: string | null): boolean;
|
|
@@ -278,10 +278,10 @@ export async function displayWarnLogs(accountId, projectName, taskId, isDeploy =
|
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
280
|
if (result && result.logs) {
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
uiLogger.warn(log
|
|
284
|
-
if (i <
|
|
281
|
+
const dedupedLogs = result.logs.reduce((acc, log) => acc.add(log.message), new Set());
|
|
282
|
+
Array.from(dedupedLogs).forEach((log, i) => {
|
|
283
|
+
uiLogger.warn(log);
|
|
284
|
+
if (i < dedupedLogs.size - 1) {
|
|
285
285
|
uiLogger.log('');
|
|
286
286
|
}
|
|
287
287
|
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { walk } from '@hubspot/local-dev-lib/fs';
|
|
4
|
-
import {
|
|
4
|
+
import { uiLogger } from '../ui/logger.js';
|
|
5
5
|
import { logError } from '../errorHandlers/index.js';
|
|
6
6
|
import { ComponentTypes, } from '../../types/Projects.js';
|
|
7
|
-
import { IR_COMPONENT_TYPES } from '../constants.js';
|
|
7
|
+
import { IR_COMPONENT_TYPES, LEGACY_PRIVATE_APP_FILE, LEGACY_PUBLIC_APP_FILE, THEME_FILE, } from '../constants.js';
|
|
8
8
|
export const CONFIG_FILES = {
|
|
9
|
-
[ComponentTypes.PrivateApp]:
|
|
10
|
-
[ComponentTypes.PublicApp]:
|
|
11
|
-
[ComponentTypes.HublTheme]:
|
|
9
|
+
[ComponentTypes.PrivateApp]: LEGACY_PRIVATE_APP_FILE,
|
|
10
|
+
[ComponentTypes.PublicApp]: LEGACY_PUBLIC_APP_FILE,
|
|
11
|
+
[ComponentTypes.HublTheme]: THEME_FILE,
|
|
12
12
|
};
|
|
13
13
|
export function getComponentTypeFromConfigFile(configFile) {
|
|
14
14
|
let key;
|
|
@@ -27,7 +27,7 @@ export function loadConfigFile(configPath) {
|
|
|
27
27
|
return parsedConfig;
|
|
28
28
|
}
|
|
29
29
|
catch (e) {
|
|
30
|
-
|
|
30
|
+
uiLogger.debug(e);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
return null;
|
package/lib/projects/upload.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ type HandleProjectUploadArg<T> = {
|
|
|
18
18
|
profile?: string;
|
|
19
19
|
};
|
|
20
20
|
export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
|
|
21
|
-
export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig): void
|
|
21
|
+
export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig, projectDir: string): Promise<void>;
|
|
22
22
|
export declare function validateNoHSMetaMismatch(srcDir: string, projectConfig: ProjectConfig): Promise<void>;
|
|
23
23
|
export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<unknown>;
|
|
24
24
|
export {};
|
package/lib/projects/upload.js
CHANGED
|
@@ -12,9 +12,11 @@ import util from 'node:util';
|
|
|
12
12
|
import { lib } from '../../lang/en.js';
|
|
13
13
|
import { ensureProjectExists } from './ensureProjectExists.js';
|
|
14
14
|
import { uiLogger } from '../ui/logger.js';
|
|
15
|
-
import {
|
|
15
|
+
import { isV2Project } from './platformVersion.js';
|
|
16
16
|
import { EXIT_CODES } from '../enums/exitCodes.js';
|
|
17
17
|
import ProjectValidationError from '../errors/ProjectValidationError.js';
|
|
18
|
+
import { walk } from '@hubspot/local-dev-lib/fs';
|
|
19
|
+
import { LEGACY_CONFIG_FILES } from '../constants.js';
|
|
18
20
|
async function uploadProjectFiles(accountId, projectName, filePath, uploadMessage, platformVersion, intermediateRepresentation) {
|
|
19
21
|
SpinniesManager.init({});
|
|
20
22
|
const accountIdentifier = uiAccountDescription(accountId) || `${accountId}`;
|
|
@@ -45,7 +47,7 @@ async function uploadProjectFiles(accountId, projectName, filePath, uploadMessag
|
|
|
45
47
|
export async function handleProjectUpload({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage = '', forceCreate = false, isUploadCommand = false, sendIR = false, skipValidation = false, }) {
|
|
46
48
|
const srcDir = path.resolve(projectDir, projectConfig.srcDir);
|
|
47
49
|
try {
|
|
48
|
-
validateSourceDirectory(srcDir, projectConfig);
|
|
50
|
+
await validateSourceDirectory(srcDir, projectConfig, projectDir);
|
|
49
51
|
}
|
|
50
52
|
catch (e) {
|
|
51
53
|
logError(e);
|
|
@@ -70,8 +72,7 @@ export async function handleProjectUpload({ accountId, projectConfig, projectDir
|
|
|
70
72
|
intermediateRepresentation = await handleTranslate(projectDir, projectConfig, accountId, skipValidation, profile);
|
|
71
73
|
}
|
|
72
74
|
catch (e) {
|
|
73
|
-
|
|
74
|
-
process.exit(EXIT_CODES.ERROR);
|
|
75
|
+
resolve({ uploadError: e });
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
await ensureProjectExists(accountId, projectConfig.name, {
|
|
@@ -105,15 +106,23 @@ export async function handleProjectUpload({ accountId, projectConfig, projectDir
|
|
|
105
106
|
archive.finalize();
|
|
106
107
|
return result;
|
|
107
108
|
}
|
|
108
|
-
export function validateSourceDirectory(srcDir, projectConfig) {
|
|
109
|
-
const
|
|
110
|
-
if (!
|
|
109
|
+
export async function validateSourceDirectory(srcDir, projectConfig, projectDir) {
|
|
110
|
+
const projectFilePaths = await walk(srcDir, ['node_modules']);
|
|
111
|
+
if (!projectFilePaths || projectFilePaths.length === 0) {
|
|
111
112
|
throw new ProjectValidationError(lib.projectUpload.handleProjectUpload.emptySource(projectConfig.srcDir));
|
|
112
113
|
}
|
|
114
|
+
if (isV2Project(projectConfig.platformVersion)) {
|
|
115
|
+
projectFilePaths.forEach(filePath => {
|
|
116
|
+
const filename = path.basename(filePath);
|
|
117
|
+
if (LEGACY_CONFIG_FILES.includes(filename)) {
|
|
118
|
+
uiLogger.warn(lib.projectUpload.handleProjectUpload.legacyFileDetected(path.relative(projectDir, filePath), projectConfig.platformVersion));
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
113
122
|
}
|
|
114
123
|
export async function validateNoHSMetaMismatch(srcDir, projectConfig) {
|
|
115
124
|
const hasHsMetaFiles = await projectContainsHsMetaFiles(srcDir);
|
|
116
|
-
if (!
|
|
125
|
+
if (!isV2Project(projectConfig.platformVersion) && hasHsMetaFiles) {
|
|
117
126
|
throw new ProjectValidationError(lib.projectUpload.wrongPlatformVersionMetaFiles);
|
|
118
127
|
}
|
|
119
128
|
}
|
package/lib/projects/urls.d.ts
CHANGED
|
@@ -7,4 +7,3 @@ export declare function getProjectBuildDetailUrl(projectName: string, buildId: n
|
|
|
7
7
|
export declare function getProjectDeployDetailUrl(projectName: string, deployId: number, accountId: number): string;
|
|
8
8
|
export declare function getLocalDevUiUrl(accountId: number, showWelcomeScreen?: boolean): string;
|
|
9
9
|
export declare function getAccountHomeUrl(accountId: number): string;
|
|
10
|
-
export declare function getAppAllowlistUrl(accountId: number, projectName: string, appUid: string): string;
|
package/lib/projects/urls.js
CHANGED
|
@@ -41,6 +41,3 @@ export function getAccountHomeUrl(accountId) {
|
|
|
41
41
|
const baseUrl = getHubSpotWebsiteOrigin(getEnv(accountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD);
|
|
42
42
|
return `${baseUrl}/home?portalId=${accountId}`;
|
|
43
43
|
}
|
|
44
|
-
export function getAppAllowlistUrl(accountId, projectName, appUid) {
|
|
45
|
-
return `${getProjectHomeUrl(accountId)}/project/${projectName}/component/${appUid}/distribution?panel=static-token-allowlist`;
|
|
46
|
-
}
|
|
@@ -11,6 +11,7 @@ vi.mock('@hubspot/local-dev-lib/api/projects', () => ({
|
|
|
11
11
|
}));
|
|
12
12
|
vi.mock('@hubspot/local-dev-lib/config', () => ({
|
|
13
13
|
getAccountId: vi.fn().mockImplementation(() => 123456789),
|
|
14
|
+
configFileExists: vi.fn().mockImplementation(() => true),
|
|
14
15
|
}));
|
|
15
16
|
describe('lib/prompts/downloadProjectPrompt', () => {
|
|
16
17
|
it('should honor the account passed as an option', async () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Separator } from '@inquirer/prompts';
|
|
2
|
-
import {
|
|
2
|
+
import { projectAddPromptV2 } from '../projectAddPrompt.js';
|
|
3
3
|
import { promptUser } from '../promptUtils.js';
|
|
4
4
|
vi.mock('../promptUtils');
|
|
5
5
|
const mockedPromptUser = vi.mocked(promptUser);
|
|
@@ -19,7 +19,7 @@ describe('lib/prompts/projectAddPrompt', () => {
|
|
|
19
19
|
supportedAuthTypes: ['oauth'],
|
|
20
20
|
supportedDistributions: ['private'],
|
|
21
21
|
};
|
|
22
|
-
describe('
|
|
22
|
+
describe('projectAddPromptV2()', () => {
|
|
23
23
|
beforeEach(() => {
|
|
24
24
|
// Mock returns empty result, logic will use selectedComponents when selectedFeatures provided
|
|
25
25
|
mockedPromptUser.mockResolvedValue({});
|
|
@@ -31,7 +31,7 @@ describe('lib/prompts/projectAddPrompt', () => {
|
|
|
31
31
|
};
|
|
32
32
|
const components = [templateChoice];
|
|
33
33
|
const selectedFeatures = ['workflow-action-tool'];
|
|
34
|
-
const result = await
|
|
34
|
+
const result = await projectAddPromptV2(components, selectedFeatures);
|
|
35
35
|
expect(result.componentTemplate).toEqual([
|
|
36
36
|
mockComponentTemplateWithCliSelector,
|
|
37
37
|
]);
|
|
@@ -49,7 +49,7 @@ describe('lib/prompts/projectAddPrompt', () => {
|
|
|
49
49
|
};
|
|
50
50
|
const components = [templateChoice];
|
|
51
51
|
const selectedFeatures = ['module'];
|
|
52
|
-
const result = await
|
|
52
|
+
const result = await projectAddPromptV2(components, selectedFeatures);
|
|
53
53
|
expect(result.componentTemplate).toEqual([mockComponentTemplate]);
|
|
54
54
|
expect(mockedPromptUser).toHaveBeenCalledWith([
|
|
55
55
|
expect.objectContaining({
|
|
@@ -65,7 +65,7 @@ describe('lib/prompts/projectAddPrompt', () => {
|
|
|
65
65
|
};
|
|
66
66
|
const components = [templateChoice];
|
|
67
67
|
const selectedFeatures = ['workflow-action-tool']; // matches cliSelector
|
|
68
|
-
const result = await
|
|
68
|
+
const result = await projectAddPromptV2(components, selectedFeatures);
|
|
69
69
|
expect(result.componentTemplate).toEqual([
|
|
70
70
|
mockComponentTemplateWithCliSelector,
|
|
71
71
|
]);
|
|
@@ -78,7 +78,7 @@ describe('lib/prompts/projectAddPrompt', () => {
|
|
|
78
78
|
const components = [templateChoice];
|
|
79
79
|
const selectedFeatures = ['non-matching-feature'];
|
|
80
80
|
mockedPromptUser.mockResolvedValue({ componentTemplate: [] });
|
|
81
|
-
const result = await
|
|
81
|
+
const result = await projectAddPromptV2(components, selectedFeatures);
|
|
82
82
|
expect(result.componentTemplate).toEqual([]);
|
|
83
83
|
});
|
|
84
84
|
it('should throw error when selected feature component is disabled', async () => {
|
|
@@ -89,7 +89,7 @@ describe('lib/prompts/projectAddPrompt', () => {
|
|
|
89
89
|
};
|
|
90
90
|
const components = [disabledTemplateChoice];
|
|
91
91
|
const selectedFeatures = ['workflow-action-tool'];
|
|
92
|
-
await expect(
|
|
92
|
+
await expect(projectAddPromptV2(components, selectedFeatures)).rejects.toThrow(/Cannot.*feature.*workflow-action/);
|
|
93
93
|
});
|
|
94
94
|
it('should handle multiple components with mixed cliSelector availability', async () => {
|
|
95
95
|
const choice1 = {
|
|
@@ -102,7 +102,7 @@ describe('lib/prompts/projectAddPrompt', () => {
|
|
|
102
102
|
};
|
|
103
103
|
const components = [choice1, choice2];
|
|
104
104
|
const selectedFeatures = ['module', 'workflow-action-tool'];
|
|
105
|
-
const result = await
|
|
105
|
+
const result = await projectAddPromptV2(components, selectedFeatures);
|
|
106
106
|
expect(result.componentTemplate).toEqual([
|
|
107
107
|
mockComponentTemplate,
|
|
108
108
|
mockComponentTemplateWithCliSelector,
|
|
@@ -116,7 +116,7 @@ describe('lib/prompts/projectAddPrompt', () => {
|
|
|
116
116
|
};
|
|
117
117
|
const components = [separator, templateChoice];
|
|
118
118
|
const selectedFeatures = ['module'];
|
|
119
|
-
const result = await
|
|
119
|
+
const result = await projectAddPromptV2(components, selectedFeatures);
|
|
120
120
|
expect(result.componentTemplate).toEqual([mockComponentTemplate]);
|
|
121
121
|
});
|
|
122
122
|
it('should prompt user when no selectedFeatures provided', async () => {
|
|
@@ -129,7 +129,7 @@ describe('lib/prompts/projectAddPrompt', () => {
|
|
|
129
129
|
mockedPromptUser.mockResolvedValue({
|
|
130
130
|
componentTemplate: [mockComponentTemplate],
|
|
131
131
|
});
|
|
132
|
-
const result = await
|
|
132
|
+
const result = await projectAddPromptV2(components, selectedFeatures);
|
|
133
133
|
expect(mockedPromptUser).toHaveBeenCalledWith([
|
|
134
134
|
expect.objectContaining({
|
|
135
135
|
name: 'componentTemplate',
|