@hubspot/cli 7.10.0-experimental.0 → 7.10.1-experimental.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/commands/project/__tests__/validate.test.js +285 -27
  2. package/commands/project/deploy.js +14 -6
  3. package/commands/project/dev/index.js +13 -4
  4. package/commands/project/migrate.js +4 -13
  5. package/commands/project/upload.js +8 -2
  6. package/commands/project/validate.js +72 -12
  7. package/lang/en.d.ts +13 -10
  8. package/lang/en.js +14 -11
  9. package/lib/__tests__/projectProfiles.test.js +273 -32
  10. package/lib/middleware/autoUpdateMiddleware.js +25 -22
  11. package/lib/middleware/fireAlarmMiddleware.js +4 -15
  12. package/lib/projectProfiles.d.ts +4 -3
  13. package/lib/projectProfiles.js +78 -32
  14. package/lib/projects/localDev/LocalDevLogger.d.ts +0 -3
  15. package/lib/projects/localDev/LocalDevLogger.js +0 -9
  16. package/lib/projects/localDev/LocalDevProcess.d.ts +0 -1
  17. package/lib/projects/localDev/LocalDevProcess.js +1 -12
  18. package/lib/projects/localDev/LocalDevState.d.ts +0 -3
  19. package/lib/projects/localDev/LocalDevState.js +0 -9
  20. package/mcp-server/utils/config.js +1 -1
  21. package/package.json +3 -4
  22. package/types/LocalDev.d.ts +0 -1
  23. package/ui/components/BoxWithTitle.d.ts +2 -1
  24. package/ui/components/BoxWithTitle.js +2 -2
  25. package/ui/components/StatusMessageBoxes.d.ts +5 -4
  26. package/ui/components/StatusMessageBoxes.js +8 -8
  27. package/lib/projects/localDev/DevSessionManager.d.ts +0 -17
  28. package/lib/projects/localDev/DevSessionManager.js +0 -56
  29. package/lib/projects/localDev/helpers/devSessionsApi.d.ts +0 -9
  30. package/lib/projects/localDev/helpers/devSessionsApi.js +0 -19
  31. package/lib/ui/boxen.d.ts +0 -5
  32. package/lib/ui/boxen.js +0 -26
@@ -1,9 +1,12 @@
1
1
  import path from 'path';
2
2
  import { loadHsProfileFile, getHsProfileFilename, getAllHsProfiles, } from '@hubspot/project-parsing-lib';
3
- import { lib } from '../lang/en.js';
3
+ import { commands, lib } from '../lang/en.js';
4
4
  import { uiBetaTag, uiLine } from './ui/index.js';
5
5
  import { uiLogger } from './ui/logger.js';
6
- import { EXIT_CODES } from './enums/exitCodes.js';
6
+ import { validateProfileVariables } from '@hubspot/project-parsing-lib/src/index.js';
7
+ import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
8
+ import SpinniesManager from './ui/SpinniesManager.js';
9
+ import { handleTranslate } from './projects/upload.js';
7
10
  export function logProfileHeader(profileName) {
8
11
  uiLine();
9
12
  uiBetaTag(lib.projectProfiles.logs.usingProfile(getHsProfileFilename(profileName)));
@@ -23,51 +26,94 @@ export function logProfileFooter(profile, includeVariables = false) {
23
26
  }
24
27
  export function loadProfile(projectConfig, projectDir, profileName) {
25
28
  if (!projectConfig || !projectDir) {
26
- uiLogger.error(lib.projectProfiles.loadProfile.errors.noProjectConfig);
27
- return;
29
+ throw new Error(lib.projectProfiles.loadProfile.errors.noProjectConfig);
28
30
  }
29
31
  const projectSourceDir = path.join(projectDir, projectConfig.srcDir);
30
32
  const profileFilename = getHsProfileFilename(profileName);
33
+ let profile;
31
34
  try {
32
- const profile = loadHsProfileFile(projectSourceDir, profileName);
33
- if (!profile) {
34
- uiLogger.error(lib.projectProfiles.loadProfile.errors.profileNotFound(profileFilename));
35
- return;
36
- }
37
- if (!profile.accountId) {
38
- uiLogger.error(lib.projectProfiles.loadProfile.errors.missingAccountId(profileFilename));
39
- return;
40
- }
41
- return profile;
35
+ profile = loadHsProfileFile(projectSourceDir, profileName);
42
36
  }
43
37
  catch (e) {
44
- uiLogger.error(lib.projectProfiles.loadProfile.errors.failedToLoadProfile(profileFilename));
45
- return;
38
+ throw new Error(lib.projectProfiles.loadProfile.errors.failedToLoadProfile(profileFilename));
39
+ }
40
+ if (!profile) {
41
+ throw new Error(lib.projectProfiles.loadProfile.errors.profileNotFound(profileFilename));
42
+ }
43
+ if (!profile.accountId) {
44
+ throw new Error(lib.projectProfiles.loadProfile.errors.missingAccountId(profileFilename));
46
45
  }
46
+ try {
47
+ getConfigAccountById(profile.accountId);
48
+ }
49
+ catch (error) {
50
+ throw new Error(lib.projectProfiles.loadProfile.errors.listedAccountNotFound(profile.accountId, profileFilename));
51
+ }
52
+ return profile;
47
53
  }
48
- export async function exitIfUsingProfiles(projectConfig, projectDir) {
54
+ export async function enforceProfileUsage(projectConfig, projectDir) {
49
55
  if (projectConfig && projectDir) {
50
56
  const existingProfiles = await getAllHsProfiles(path.join(projectDir, projectConfig.srcDir));
51
57
  if (existingProfiles.length > 0) {
52
- uiLogger.error(lib.projectProfiles.exitIfUsingProfiles.errors.noProfileSpecified);
53
- process.exit(EXIT_CODES.ERROR);
58
+ throw new Error(lib.projectProfiles.exitIfUsingProfiles.errors.noProfileSpecified);
54
59
  }
55
60
  }
56
61
  }
57
- export async function loadAndValidateProfile(projectConfig, projectDir, argsProfile) {
58
- if (argsProfile) {
59
- logProfileHeader(argsProfile);
60
- const profile = loadProfile(projectConfig, projectDir, argsProfile);
61
- if (!profile) {
62
- uiLine();
63
- process.exit(EXIT_CODES.ERROR);
64
- }
62
+ export async function loadAndValidateProfile(projectConfig, projectDir, profileName, silent = false) {
63
+ if (!profileName) {
64
+ await enforceProfileUsage(projectConfig, projectDir);
65
+ return;
66
+ }
67
+ if (!silent) {
68
+ logProfileHeader(profileName);
69
+ }
70
+ const profile = loadProfile(projectConfig, projectDir, profileName);
71
+ if (!silent) {
65
72
  logProfileFooter(profile, true);
66
- return profile.accountId;
67
73
  }
68
- else {
69
- // A profile must be specified if this project has profiles configured
70
- await exitIfUsingProfiles(projectConfig, projectDir);
74
+ if (profile.variables) {
75
+ const validationResult = validateProfileVariables(profile.variables, profileName);
76
+ if (!validationResult.success) {
77
+ throw new Error(lib.projectProfiles.loadProfile.errors.profileNotValid(getHsProfileFilename(profileName), validationResult.errors));
78
+ }
79
+ }
80
+ return profile.accountId;
81
+ // A profile must be specified if this project has profiles configured
82
+ }
83
+ export async function validateProjectForProfile(projectConfig, projectDir, profileName, derivedAccountId, indentSpinners = false) {
84
+ let targetAccountId = derivedAccountId;
85
+ const spinnerName = `validatingProfile-${profileName}`;
86
+ const profileFilename = getHsProfileFilename(profileName);
87
+ SpinniesManager.init();
88
+ SpinniesManager.add(spinnerName, {
89
+ text: commands.project.validate.spinners.validatingProfile(profileFilename),
90
+ indent: indentSpinners ? 4 : 0,
91
+ });
92
+ try {
93
+ const accountId = await loadAndValidateProfile(projectConfig, projectDir, profileName, true);
94
+ targetAccountId = accountId || derivedAccountId;
95
+ }
96
+ catch (error) {
97
+ SpinniesManager.fail(spinnerName, {
98
+ text: commands.project.validate.spinners.profileValidationFailed(profileFilename),
99
+ });
100
+ return [error instanceof Error ? error.message : `${error}`];
101
+ }
102
+ try {
103
+ await handleTranslate(projectDir, projectConfig, targetAccountId, false, profileName);
104
+ }
105
+ catch (error) {
106
+ SpinniesManager.fail(spinnerName, {
107
+ text: commands.project.validate.spinners.invalidWithProfile(profileFilename, projectConfig.name),
108
+ });
109
+ const errors = [
110
+ commands.project.validate.failure(projectConfig.name),
111
+ ];
112
+ errors.push(error instanceof Error ? error : `${error}`);
113
+ return errors;
71
114
  }
72
- return undefined;
115
+ SpinniesManager.succeed(spinnerName, {
116
+ text: commands.project.validate.spinners.profileValidationSucceeded(profileFilename),
117
+ });
118
+ return [];
73
119
  }
@@ -12,9 +12,6 @@ declare class LocalDevLogger {
12
12
  devServerSetupError(e: unknown): void;
13
13
  devServerStartError(e: unknown): void;
14
14
  devServerCleanupError(e: unknown): void;
15
- devSessionRegistrationError(e: unknown): void;
16
- devSessionHeartbeatError(e: unknown): void;
17
- devSessionDeletionError(e: unknown): void;
18
15
  resetSpinnies(): void;
19
16
  startupMessage(): void;
20
17
  cleanupStart(): void;
@@ -67,15 +67,6 @@ class LocalDevLogger {
67
67
  devServerCleanupError(e) {
68
68
  this.handleError(e, lib.LocalDevManager.devServer.cleanupError);
69
69
  }
70
- devSessionRegistrationError(e) {
71
- this.handleError(e, lib.LocalDevManager.devSession.registrationError);
72
- }
73
- devSessionHeartbeatError(e) {
74
- this.handleError(e, lib.LocalDevManager.devSession.heartbeatError);
75
- }
76
- devSessionDeletionError(e) {
77
- this.handleError(e, lib.LocalDevManager.devSession.deletionError);
78
- }
79
70
  resetSpinnies() {
80
71
  SpinniesManager.stopAll();
81
72
  SpinniesManager.init();
@@ -7,7 +7,6 @@ declare class LocalDevProcess {
7
7
  private state;
8
8
  private _logger;
9
9
  private devServerManager;
10
- private devSessionManager;
11
10
  constructor(options: LocalDevStateConstructorOptions);
12
11
  get projectDir(): string;
13
12
  get projectData(): Project;
@@ -6,7 +6,6 @@ import open from 'open';
6
6
  import LocalDevState from './LocalDevState.js';
7
7
  import LocalDevLogger from './LocalDevLogger.js';
8
8
  import DevServerManager from './DevServerManager.js';
9
- import DevSessionManager from './DevSessionManager.js';
10
9
  import { EXIT_CODES } from '../../enums/exitCodes.js';
11
10
  import { getProjectConfig } from '../config.js';
12
11
  import { handleProjectUpload } from '../upload.js';
@@ -21,7 +20,6 @@ class LocalDevProcess {
21
20
  state;
22
21
  _logger;
23
22
  devServerManager;
24
- devSessionManager;
25
23
  constructor(options) {
26
24
  this.state = new LocalDevState(options);
27
25
  this._logger = new LocalDevLogger(this.state);
@@ -29,10 +27,6 @@ class LocalDevProcess {
29
27
  localDevState: this.state,
30
28
  logger: this._logger,
31
29
  });
32
- this.devSessionManager = new DevSessionManager({
33
- localDevState: this.state,
34
- localDevLogger: this._logger,
35
- });
36
30
  }
37
31
  get projectDir() {
38
32
  return this.state.projectDir;
@@ -155,10 +149,6 @@ class LocalDevProcess {
155
149
  this.openLocalDevUi();
156
150
  }
157
151
  await this.startDevServers();
158
- const devSessionRegistered = await this.devSessionManager.registerDevSession();
159
- if (!devSessionRegistered) {
160
- process.exit(EXIT_CODES.ERROR);
161
- }
162
152
  this.state.devServersStarted = true;
163
153
  this.logger.monitorConsoleOutput();
164
154
  }
@@ -166,8 +156,7 @@ class LocalDevProcess {
166
156
  if (showProgress) {
167
157
  this.logger.cleanupStart();
168
158
  }
169
- let cleanupSucceeded = await this.cleanupDevServers();
170
- cleanupSucceeded = await this.devSessionManager.deleteDevSession();
159
+ const cleanupSucceeded = await this.cleanupDevServers();
171
160
  if (!cleanupSucceeded) {
172
161
  if (showProgress) {
173
162
  this.logger.cleanupError();
@@ -20,7 +20,6 @@ declare class LocalDevState {
20
20
  private _devServerMessage;
21
21
  private _uploadWarnings;
22
22
  private _devServersStarted;
23
- private _devSessionId;
24
23
  constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectData, debug, initialProjectNodes, initialProjectProfileData, profile, env, }: LocalDevStateConstructorOptions);
25
24
  private runListeners;
26
25
  get targetProjectAccountId(): number;
@@ -55,8 +54,6 @@ declare class LocalDevState {
55
54
  get uploadWarnings(): Set<string>;
56
55
  get devServersStarted(): boolean;
57
56
  set devServersStarted(started: boolean);
58
- get devSessionId(): number | undefined;
59
- set devSessionId(sessionId: number | undefined);
60
57
  addUploadWarning(warning: string): void;
61
58
  clearUploadWarnings(): void;
62
59
  addListener<K extends keyof LocalDevState>(key: K, listener: LocalDevStateListener<K>): void;
@@ -16,7 +16,6 @@ class LocalDevState {
16
16
  _devServerMessage;
17
17
  _uploadWarnings;
18
18
  _devServersStarted;
19
- _devSessionId;
20
19
  constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectData, debug, initialProjectNodes, initialProjectProfileData, profile, env, }) {
21
20
  this._targetProjectAccountId = targetProjectAccountId;
22
21
  this._targetTestingAccountId = targetTestingAccountId;
@@ -33,7 +32,6 @@ class LocalDevState {
33
32
  this._devServerMessage = LOCAL_DEV_SERVER_MESSAGE_TYPES.INITIAL;
34
33
  this._uploadWarnings = new Set();
35
34
  this._devServersStarted = false;
36
- this._devSessionId = undefined;
37
35
  this._listeners = {};
38
36
  }
39
37
  runListeners(key) {
@@ -117,13 +115,6 @@ class LocalDevState {
117
115
  this._devServersStarted = started;
118
116
  this.runListeners('devServersStarted');
119
117
  }
120
- get devSessionId() {
121
- return this._devSessionId;
122
- }
123
- set devSessionId(sessionId) {
124
- this._devSessionId = sessionId;
125
- this.runListeners('devSessionId');
126
- }
127
118
  addUploadWarning(warning) {
128
119
  this.uploadWarnings.add(warning);
129
120
  this.runListeners('uploadWarnings');
@@ -3,7 +3,7 @@ export function setupHubSpotConfig(absoluteCurrentWorkingDirectory) {
3
3
  if (!absoluteCurrentWorkingDirectory) {
4
4
  return;
5
5
  }
6
- const configPath = getLocalConfigFilePathIfExists(absoluteCurrentWorkingDirectory);
6
+ const configPath = getLocalConfigFilePathIfExists();
7
7
  if (configPath) {
8
8
  process.env.HUBSPOT_CONFIG_PATH = configPath;
9
9
  }
package/package.json CHANGED
@@ -1,18 +1,17 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "7.10.0-experimental.0",
3
+ "version": "7.10.1-experimental.0",
4
4
  "description": "The official CLI for developing on HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "https://github.com/HubSpot/hubspot-cli",
7
7
  "type": "module",
8
8
  "dependencies": {
9
9
  "@hubspot/local-dev-lib": "4.0.1",
10
- "@hubspot/project-parsing-lib": "0.10.2",
10
+ "@hubspot/project-parsing-lib": "0.10.3",
11
11
  "@hubspot/serverless-dev-runtime": "7.0.7",
12
12
  "@hubspot/theme-preview-dev-server": "0.0.12",
13
13
  "@hubspot/ui-extensions-dev-server": "1.0.0",
14
14
  "archiver": "7.0.1",
15
- "boxen": "8.0.1",
16
15
  "chalk": "5.4.1",
17
16
  "chokidar": "3.6.0",
18
17
  "cli-cursor": "3.1.0",
@@ -36,7 +35,7 @@
36
35
  "yargs-parser": "21.1.1"
37
36
  },
38
37
  "devDependencies": {
39
- "@hubspot/npm-scripts": "0.0.5",
38
+ "@hubspot/npm-scripts": "0.0.6-beta.0",
40
39
  "@types/archiver": "^6.0.3",
41
40
  "@types/cli-progress": "^3.11.6",
42
41
  "@types/express": "^5.0.0",
@@ -18,7 +18,6 @@ export type LocalDevStateConstructorOptions = {
18
18
  };
19
19
  initialProjectProfileData: HSProfileVariables;
20
20
  env: Environment;
21
- devSessionId?: number;
22
21
  };
23
22
  export type LocalDevWebsocketMessage = {
24
23
  type: string;
@@ -3,6 +3,7 @@ export interface BoxWithTitleProps {
3
3
  message: string;
4
4
  titleBackgroundColor?: string;
5
5
  borderColor?: string;
6
+ textCentered?: boolean;
6
7
  }
7
8
  export declare function getBoxWithTitle(props: BoxWithTitleProps): React.ReactNode;
8
- export declare function BoxWithTitle({ title, message, titleBackgroundColor, borderColor, }: BoxWithTitleProps): React.ReactNode;
9
+ export declare function BoxWithTitle({ title, message, titleBackgroundColor, borderColor, textCentered, }: BoxWithTitleProps): React.ReactNode;
@@ -4,6 +4,6 @@ import { CONTAINER_STYLES } from '../styles.js';
4
4
  export function getBoxWithTitle(props) {
5
5
  return _jsx(BoxWithTitle, { ...props });
6
6
  }
7
- export function BoxWithTitle({ title, message, titleBackgroundColor, borderColor, }) {
8
- return (_jsxs(Box, { ...CONTAINER_STYLES, borderStyle: "round", borderColor: borderColor, children: [_jsx(Box, { position: "absolute", marginTop: -2, paddingX: 0, alignSelf: "flex-start", justifyContent: "center", alignItems: "center", children: _jsx(Text, { backgroundColor: titleBackgroundColor, bold: true, children: ` ${title} ` }) }), _jsx(Box, { justifyContent: "center", alignItems: "center", children: _jsx(Text, { children: message }) })] }));
7
+ export function BoxWithTitle({ title, message, titleBackgroundColor, borderColor, textCentered, }) {
8
+ return (_jsxs(Box, { ...CONTAINER_STYLES, borderStyle: "round", borderColor: borderColor, alignSelf: "flex-start", children: [_jsx(Box, { position: "absolute", marginTop: -2, paddingX: 0, alignSelf: "flex-start", justifyContent: "center", alignItems: "center", children: _jsx(Text, { backgroundColor: titleBackgroundColor, bold: true, children: ` ${title} ` }) }), _jsx(Box, { flexDirection: "column", alignItems: textCentered ? 'center' : 'flex-start', width: "100%", children: message.split('\n').map((line, i) => (_jsx(Text, { children: line }, `${i}-${line}`))) })] }));
9
9
  }
@@ -1,12 +1,13 @@
1
1
  export interface StatusMessageBoxProps {
2
2
  title: string;
3
3
  message: string;
4
+ textCentered?: boolean;
4
5
  }
5
6
  export declare function getWarningBox(props: StatusMessageBoxProps): React.ReactNode;
6
- export declare function WarningBox({ title, message, }: StatusMessageBoxProps): React.ReactNode;
7
+ export declare function WarningBox({ title, message, textCentered, }: StatusMessageBoxProps): React.ReactNode;
7
8
  export declare function getAlertBox(props: StatusMessageBoxProps): React.ReactNode;
8
- export declare function AlertBox({ title, message, }: StatusMessageBoxProps): React.ReactNode;
9
+ export declare function AlertBox({ title, message, textCentered, }: StatusMessageBoxProps): React.ReactNode;
9
10
  export declare function getSuccessBox(props: StatusMessageBoxProps): React.ReactNode;
10
- export declare function SuccessBox({ title, message, }: StatusMessageBoxProps): React.ReactNode;
11
+ export declare function SuccessBox({ title, message, textCentered, }: StatusMessageBoxProps): React.ReactNode;
11
12
  export declare function getInfoBox(props: StatusMessageBoxProps): React.ReactNode;
12
- export declare function InfoBox({ title, message, }: StatusMessageBoxProps): React.ReactNode;
13
+ export declare function InfoBox({ title, message, textCentered, }: StatusMessageBoxProps): React.ReactNode;
@@ -4,28 +4,28 @@ import { BoxWithTitle } from './BoxWithTitle.js';
4
4
  export function getWarningBox(props) {
5
5
  return _jsx(WarningBox, { ...props });
6
6
  }
7
- export function WarningBox({ title, message, }) {
7
+ export function WarningBox({ title, message, textCentered, }) {
8
8
  const color = INK_COLORS.WARNING_YELLOW;
9
- return (_jsx(BoxWithTitle, { title: title, message: message, titleBackgroundColor: color, borderColor: color }));
9
+ return (_jsx(BoxWithTitle, { title: title, message: message, titleBackgroundColor: color, borderColor: color, textCentered: textCentered }));
10
10
  }
11
11
  export function getAlertBox(props) {
12
12
  return _jsx(AlertBox, { ...props });
13
13
  }
14
- export function AlertBox({ title, message, }) {
14
+ export function AlertBox({ title, message, textCentered, }) {
15
15
  const color = INK_COLORS.ALERT_RED;
16
- return (_jsx(BoxWithTitle, { title: title, message: message, titleBackgroundColor: color, borderColor: color }));
16
+ return (_jsx(BoxWithTitle, { title: title, message: message, titleBackgroundColor: color, borderColor: color, textCentered: textCentered }));
17
17
  }
18
18
  export function getSuccessBox(props) {
19
19
  return _jsx(SuccessBox, { ...props });
20
20
  }
21
- export function SuccessBox({ title, message, }) {
21
+ export function SuccessBox({ title, message, textCentered, }) {
22
22
  const color = INK_COLORS.SUCCESS_GREEN;
23
- return (_jsx(BoxWithTitle, { title: title, message: message, titleBackgroundColor: color, borderColor: color }));
23
+ return (_jsx(BoxWithTitle, { title: title, message: message, titleBackgroundColor: color, borderColor: color, textCentered: textCentered }));
24
24
  }
25
25
  export function getInfoBox(props) {
26
26
  return _jsx(InfoBox, { ...props });
27
27
  }
28
- export function InfoBox({ title, message, }) {
28
+ export function InfoBox({ title, message, textCentered, }) {
29
29
  const color = INK_COLORS.INFO_BLUE;
30
- return (_jsx(BoxWithTitle, { title: title, message: message, titleBackgroundColor: color, borderColor: color }));
30
+ return (_jsx(BoxWithTitle, { title: title, message: message, titleBackgroundColor: color, borderColor: color, textCentered: textCentered }));
31
31
  }
@@ -1,17 +0,0 @@
1
- import LocalDevState from './LocalDevState.js';
2
- import LocalDevLogger from './LocalDevLogger.js';
3
- type DevSessionManagerConstructorOptions = {
4
- localDevState: LocalDevState;
5
- localDevLogger: LocalDevLogger;
6
- };
7
- declare class DevSessionManager {
8
- localDevState: LocalDevState;
9
- localDevLogger: LocalDevLogger;
10
- private _devSessionId;
11
- private _heartbeatInterval;
12
- constructor(options: DevSessionManagerConstructorOptions);
13
- registerDevSession(): Promise<boolean>;
14
- private initializeHeartbeat;
15
- deleteDevSession(): Promise<boolean>;
16
- }
17
- export default DevSessionManager;
@@ -1,56 +0,0 @@
1
- import { getActiveServers } from '@hubspot/local-dev-lib/portManager';
2
- import { devSessionHeartbeat, registerDevSession, deleteDevSession, } from './helpers/devSessionsApi.js';
3
- class DevSessionManager {
4
- localDevState;
5
- localDevLogger;
6
- _devSessionId;
7
- _heartbeatInterval;
8
- constructor(options) {
9
- this.localDevState = options.localDevState;
10
- this.localDevLogger = options.localDevLogger;
11
- this._devSessionId = undefined;
12
- this._heartbeatInterval = undefined;
13
- }
14
- async registerDevSession() {
15
- try {
16
- const activeServers = await getActiveServers();
17
- const portData = Object.entries(activeServers).map(([serverId, port]) => ({ serverId, port }));
18
- const registerDevSessionResponse = await registerDevSession(this.localDevState.targetTestingAccountId, portData);
19
- this._devSessionId = registerDevSessionResponse.data.sessionId;
20
- }
21
- catch (e) {
22
- this.localDevLogger.devSessionRegistrationError(e);
23
- return false;
24
- }
25
- this.initializeHeartbeat();
26
- return true;
27
- }
28
- initializeHeartbeat() {
29
- this._heartbeatInterval = setInterval(() => {
30
- if (!this._devSessionId) {
31
- return;
32
- }
33
- try {
34
- devSessionHeartbeat(this.localDevState.targetTestingAccountId, this._devSessionId);
35
- }
36
- catch (e) {
37
- // TODO: What do we do if the heartbeat fails?
38
- this.localDevLogger.devSessionHeartbeatError(e);
39
- }
40
- }, 30000);
41
- }
42
- async deleteDevSession() {
43
- if (this._devSessionId) {
44
- clearInterval(this._heartbeatInterval);
45
- try {
46
- await deleteDevSession(this.localDevState.targetProjectAccountId, this._devSessionId);
47
- }
48
- catch (e) {
49
- this.localDevLogger.devSessionDeletionError(e);
50
- return false;
51
- }
52
- }
53
- return true;
54
- }
55
- }
56
- export default DevSessionManager;
@@ -1,9 +0,0 @@
1
- import { HubSpotPromise } from '@hubspot/local-dev-lib/types/Http';
2
- export declare function registerDevSession(accountId: number, ports: {
3
- serverId: string;
4
- port: number;
5
- }[], force?: boolean): HubSpotPromise<{
6
- sessionId: number;
7
- }>;
8
- export declare function devSessionHeartbeat(accountId: number, sessionId: number): HubSpotPromise<void>;
9
- export declare function deleteDevSession(accountId: number, sessionId: number): HubSpotPromise<void>;
@@ -1,19 +0,0 @@
1
- import { http } from '@hubspot/local-dev-lib/http';
2
- const DEV_SESSIONS_API_PATH = 'projects-localdev/2025-09/dev-sessions';
3
- export async function registerDevSession(accountId, ports, force) {
4
- return http.post(accountId, {
5
- url: `${DEV_SESSIONS_API_PATH}/register${force ? '?force=true' : ''}`,
6
- data: { ports },
7
- });
8
- }
9
- export async function devSessionHeartbeat(accountId, sessionId) {
10
- return http.post(accountId, {
11
- url: `${DEV_SESSIONS_API_PATH}/${sessionId}/heartbeat`,
12
- data: {},
13
- });
14
- }
15
- export async function deleteDevSession(accountId, sessionId) {
16
- return http.delete(accountId, {
17
- url: `${DEV_SESSIONS_API_PATH}/${sessionId}`,
18
- });
19
- }
package/lib/ui/boxen.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import { Options } from 'boxen';
2
- export declare function logInBox({ contents, options, }: {
3
- contents: string;
4
- options?: Options;
5
- }): Promise<void>;
package/lib/ui/boxen.js DELETED
@@ -1,26 +0,0 @@
1
- import { uiLogger } from './logger.js';
2
- import { UI_COLORS } from './index.js';
3
- import { lib } from '../../lang/en.js';
4
- const defaultOptions = {
5
- titleAlignment: 'left',
6
- borderColor: UI_COLORS.MARIGOLD,
7
- margin: 1,
8
- padding: 1,
9
- textAlignment: 'left',
10
- borderStyle: 'round',
11
- };
12
- export async function logInBox({ contents, options, }) {
13
- try {
14
- const boxen = (await import('boxen')).default;
15
- uiLogger.log(boxen(contents, { ...defaultOptions, ...options }));
16
- return;
17
- }
18
- catch (error) {
19
- uiLogger.debug(lib.boxen.failedToLoad);
20
- if (options?.title) {
21
- uiLogger.log(options.title);
22
- uiLogger.log('');
23
- }
24
- uiLogger.log(contents);
25
- }
26
- }