@hubspot/cli 7.8.0-experimental.0 → 7.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +31 -27
- 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 +1 -3
- package/commands/getStarted.js +68 -20
- 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 +4 -11
- 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 +15 -8
- 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 +33 -12
- 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 +365 -111
- 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__/hasFeature.test.js +145 -7
- 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 +22 -1
- package/lib/constants.js +26 -1
- package/lib/dependencyManagement.d.ts +0 -5
- package/lib/dependencyManagement.js +9 -36
- 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/hasFeature.js +6 -0
- 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} +16 -13
- 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 +3 -2
- package/lib/projects/localDev/helpers/project.js +49 -10
- 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 +112 -8
- 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/HsCreateFunctionTool.js +1 -1
- package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +2 -2
- package/mcp-server/tools/cms/HsCreateModuleTool.js +1 -1
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +1 -1
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +2 -2
- package/mcp-server/tools/cms/HsListFunctionsTool.js +1 -1
- package/mcp-server/tools/cms/HsListTool.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.js +2 -2
- package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsListTool.test.js +1 -1
- package/mcp-server/tools/index.js +4 -0
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +3 -3
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +3 -3
- package/mcp-server/tools/project/CreateProjectTool.d.ts +3 -3
- package/mcp-server/tools/project/CreateProjectTool.js +5 -5
- package/mcp-server/tools/project/DeployProjectTool.js +1 -1
- package/mcp-server/tools/project/DocFetchTool.js +2 -2
- package/mcp-server/tools/project/DocsSearchTool.d.ts +4 -1
- package/mcp-server/tools/project/DocsSearchTool.js +7 -7
- 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 +13 -7
- package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +2 -2
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +1 -1
- package/mcp-server/tools/project/UploadProjectTools.js +2 -2
- package/mcp-server/tools/project/ValidateProjectTool.js +1 -1
- package/mcp-server/tools/project/__tests__/AddFeatureToProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +2 -2
- package/mcp-server/tools/project/__tests__/DeployProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +2 -2
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +14 -12
- 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 +9 -8
- package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +1 -1
- package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +1 -1
- package/mcp-server/tools/project/constants.d.ts +1 -1
- package/mcp-server/tools/project/constants.js +9 -3
- 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 -12
- package/types/LocalDev.d.ts +19 -3
- package/ui/components/HorizontalSelectPrompt.js +1 -1
- package/ui/index.js +1 -1
- package/commands/getStartedV2.d.ts +0 -9
- package/commands/getStartedV2.js +0 -39
- 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/ui/components/Ascii.d.ts +0 -10
- package/ui/components/Ascii.js +0 -11
- package/ui/views/GetStarted.d.ts +0 -7
- package/ui/views/GetStarted.js +0 -157
- /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
|
@@ -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) {
|
|
@@ -6,7 +6,8 @@ export declare function createNewProjectForLocalDev(projectConfig: ProjectConfig
|
|
|
6
6
|
export declare function createInitialBuildForNewProject(projectConfig: ProjectConfig, projectDir: string, targetAccountId: number, sendIR?: boolean, profile?: string): Promise<Build>;
|
|
7
7
|
export declare function compareLocalProjectToDeployed(projectConfig: ProjectConfig, accountId: number, deployedBuildId: number | undefined, localProjectNodes: {
|
|
8
8
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
9
|
-
}): Promise<void>;
|
|
9
|
+
}, profile?: string): Promise<void>;
|
|
10
10
|
export declare function isDeployedProjectUpToDateWithLocal(projectConfig: ProjectConfig, accountId: number, deployedBuildId: number, localProjectNodes: {
|
|
11
11
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
12
|
-
}): Promise<boolean>;
|
|
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
|
|
@@ -123,7 +124,7 @@ export async function createInitialBuildForNewProject(projectConfig, projectDir,
|
|
|
123
124
|
}
|
|
124
125
|
return initialUploadResult.buildResult;
|
|
125
126
|
}
|
|
126
|
-
export async function compareLocalProjectToDeployed(projectConfig, accountId, deployedBuildId, localProjectNodes) {
|
|
127
|
+
export async function compareLocalProjectToDeployed(projectConfig, accountId, deployedBuildId, localProjectNodes, profile) {
|
|
127
128
|
uiLogger.log('');
|
|
128
129
|
if (!deployedBuildId) {
|
|
129
130
|
uiLogger.error(lib.localDevHelpers.project.compareLocalProjectToDeployed.noDeployedBuild(projectConfig.name, uiAccountDescription(accountId)));
|
|
@@ -132,7 +133,7 @@ export async function compareLocalProjectToDeployed(projectConfig, accountId, de
|
|
|
132
133
|
SpinniesManager.add('compareLocalProjectToDeployed', {
|
|
133
134
|
text: lib.localDevHelpers.project.compareLocalProjectToDeployed.checking,
|
|
134
135
|
});
|
|
135
|
-
const isUpToDate = await isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes);
|
|
136
|
+
const isUpToDate = await isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes, profile);
|
|
136
137
|
if (isUpToDate) {
|
|
137
138
|
SpinniesManager.succeed('compareLocalProjectToDeployed', {
|
|
138
139
|
text: lib.localDevHelpers.project.compareLocalProjectToDeployed.upToDate,
|
|
@@ -144,26 +145,28 @@ export async function compareLocalProjectToDeployed(projectConfig, accountId, de
|
|
|
144
145
|
.notUpToDate,
|
|
145
146
|
});
|
|
146
147
|
uiLogger.log('');
|
|
147
|
-
uiLogger.log(lib.localDevHelpers.project.compareLocalProjectToDeployed
|
|
148
|
-
.notUpToDateExplanation);
|
|
148
|
+
uiLogger.log(lib.localDevHelpers.project.compareLocalProjectToDeployed.notUpToDateExplanation(profile));
|
|
149
149
|
process.exit(EXIT_CODES.SUCCESS);
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
-
export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes) {
|
|
152
|
+
export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes, profile) {
|
|
153
153
|
let tempDir = null;
|
|
154
154
|
try {
|
|
155
155
|
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'hubspot-project-compare-'));
|
|
156
156
|
const { data: zippedProject } = await downloadProject(accountId, projectConfig.name, deployedBuildId);
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
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);
|
|
160
159
|
const { intermediateNodesIndexedByUid: deployedProjectNodes } = await translate({
|
|
161
160
|
projectSourceDir: deployedProjectSourceDir,
|
|
162
161
|
platformVersion: projectConfig.platformVersion,
|
|
163
162
|
accountId: accountId,
|
|
164
|
-
}, {});
|
|
163
|
+
}, { profile });
|
|
165
164
|
return isDeepEqual(localProjectNodes, deployedProjectNodes, ['localDev']);
|
|
166
165
|
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
debugError(err);
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
167
170
|
finally {
|
|
168
171
|
// Clean up temporary directory
|
|
169
172
|
if (tempDir && (await fs.pathExists(tempDir))) {
|
|
@@ -171,3 +174,39 @@ export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountI
|
|
|
171
174
|
}
|
|
172
175
|
}
|
|
173
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',
|