@hubspot/cli 7.7.0-experimental.3 → 7.7.2-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 (98) hide show
  1. package/bin/cli.js +96 -94
  2. package/commands/account/auth.js +51 -82
  3. package/commands/account.js +0 -2
  4. package/commands/app.js +0 -2
  5. package/commands/auth.js +2 -17
  6. package/commands/cms.js +0 -2
  7. package/commands/completion.js +0 -2
  8. package/commands/config/migrate.js +17 -36
  9. package/commands/config.js +0 -2
  10. package/commands/create.js +0 -2
  11. package/commands/customObject.js +0 -2
  12. package/commands/doctor.js +0 -2
  13. package/commands/feedback.js +0 -2
  14. package/commands/filemanager.js +0 -2
  15. package/commands/function.js +0 -2
  16. package/commands/hubdb.js +0 -2
  17. package/commands/init.js +1 -4
  18. package/commands/lint.js +0 -2
  19. package/commands/list.js +0 -2
  20. package/commands/module/marketplace-validate.js +6 -8
  21. package/commands/module.js +2 -1
  22. package/commands/mv.js +0 -2
  23. package/commands/open.js +0 -2
  24. package/commands/project/add.d.ts +5 -2
  25. package/commands/project/add.js +43 -80
  26. package/commands/project/create.d.ts +2 -8
  27. package/commands/project/create.js +84 -55
  28. package/commands/project/dev/deprecatedFlow.d.ts +8 -2
  29. package/commands/project/dev/deprecatedFlow.js +9 -1
  30. package/commands/project/dev/index.js +59 -34
  31. package/commands/project/dev/unifiedFlow.d.ts +10 -2
  32. package/commands/project/dev/unifiedFlow.js +28 -41
  33. package/commands/project.js +0 -2
  34. package/commands/remove.js +6 -14
  35. package/commands/sandbox.js +0 -2
  36. package/commands/secret.js +0 -2
  37. package/commands/theme/generate-selectors.js +7 -10
  38. package/commands/theme/marketplace-validate.js +6 -8
  39. package/commands/theme/preview.js +17 -18
  40. package/commands/theme.js +2 -4
  41. package/commands/upload.js +26 -65
  42. package/commands/watch.js +20 -32
  43. package/lang/en.d.ts +154 -95
  44. package/lang/en.js +156 -100
  45. package/lang/en.lyaml +3 -186
  46. package/lib/accountTypes.js +1 -3
  47. package/lib/commonOpts.d.ts +1 -3
  48. package/lib/commonOpts.js +1 -1
  49. package/lib/configMigrate.d.ts +2 -2
  50. package/lib/configMigrate.js +34 -69
  51. package/lib/constants.d.ts +23 -5
  52. package/lib/constants.js +24 -6
  53. package/lib/generateSelectors.js +3 -5
  54. package/lib/marketplaceValidate.d.ts +12 -2
  55. package/lib/marketplaceValidate.js +22 -29
  56. package/lib/middleware/configMiddleware.js +1 -0
  57. package/lib/middleware/fireAlarmMiddleware.d.ts +2 -2
  58. package/lib/middleware/fireAlarmMiddleware.js +5 -3
  59. package/lib/projects/add/legacyAddComponent.d.ts +5 -0
  60. package/lib/projects/add/legacyAddComponent.js +48 -0
  61. package/lib/projects/add/v3AddComponent.d.ts +8 -0
  62. package/lib/projects/add/v3AddComponent.js +85 -0
  63. package/lib/projects/components.d.ts +2 -0
  64. package/lib/projects/components.js +82 -0
  65. package/lib/projects/create/index.d.ts +23 -0
  66. package/lib/projects/create/index.js +33 -0
  67. package/lib/projects/create/legacy.d.ts +6 -0
  68. package/lib/projects/{create.js → create/legacy.js} +20 -11
  69. package/lib/projects/create/v3.d.ts +27 -0
  70. package/lib/projects/create/v3.js +158 -0
  71. package/lib/projects/localDev/AppDevModeInterface.d.ts +3 -2
  72. package/lib/projects/localDev/AppDevModeInterface.js +38 -8
  73. package/lib/projects/localDev/LocalDevProcess.d.ts +12 -5
  74. package/lib/projects/localDev/LocalDevProcess.js +47 -17
  75. package/lib/projects/localDev/LocalDevState.d.ts +16 -3
  76. package/lib/projects/localDev/LocalDevState.js +43 -2
  77. package/lib/projects/localDev/LocalDevWatcher.js +3 -6
  78. package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +3 -0
  79. package/lib/projects/localDev/LocalDevWebsocketServer.js +48 -9
  80. package/lib/projects/upload.js +6 -0
  81. package/lib/prompts/createProjectPrompt.d.ts +14 -5
  82. package/lib/prompts/createProjectPrompt.js +36 -13
  83. package/lib/prompts/projectAddPrompt.d.ts +5 -1
  84. package/lib/prompts/projectAddPrompt.js +35 -7
  85. package/lib/prompts/promptUtils.d.ts +0 -1
  86. package/lib/prompts/promptUtils.js +0 -2
  87. package/lib/prompts/setAsDefaultAccountPrompt.js +10 -0
  88. package/package.json +7 -6
  89. package/types/LocalDev.d.ts +11 -1
  90. package/types/Projects.d.ts +19 -2
  91. package/types/Yargs.d.ts +2 -0
  92. package/commands/testAccount/create.d.ts +0 -7
  93. package/commands/testAccount/create.js +0 -118
  94. package/commands/testAccount/delete.d.ts +0 -6
  95. package/commands/testAccount/delete.js +0 -42
  96. package/commands/testAccount.d.ts +0 -3
  97. package/commands/testAccount.js +0 -27
  98. package/lib/projects/create.d.ts +0 -5
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PROJECT_WITH_APP = exports.EMPTY_PROJECT = void 0;
7
+ exports.createV3App = createV3App;
8
+ exports.calculateComponentTemplateChoices = calculateComponentTemplateChoices;
9
+ exports.v3ComponentFlow = v3ComponentFlow;
10
+ exports.generateComponentPaths = generateComponentPaths;
11
+ const constants_1 = require("../../constants");
12
+ const en_1 = require("../../../lang/en");
13
+ const promptUtils_1 = require("../../prompts/promptUtils");
14
+ const chalk_1 = __importDefault(require("chalk"));
15
+ const buildAndDeploy_1 = require("../buildAndDeploy");
16
+ const path_1 = __importDefault(require("path"));
17
+ const legacy_1 = require("./legacy");
18
+ const errorHandlers_1 = require("../../errorHandlers");
19
+ const exitCodes_1 = require("../../enums/exitCodes");
20
+ const inquirer = require('inquirer');
21
+ exports.EMPTY_PROJECT = 'empty';
22
+ exports.PROJECT_WITH_APP = 'app';
23
+ async function createV3App(providedAuth, providedDistribution) {
24
+ let authType;
25
+ if (providedAuth &&
26
+ providedDistribution === constants_1.marketplaceDistribution &&
27
+ providedAuth !== constants_1.oAuth) {
28
+ throw new Error(en_1.lib.projects.create.errors.invalidAuthDistCombo(providedAuth, providedDistribution));
29
+ }
30
+ const distribution = providedDistribution ||
31
+ (await (0, promptUtils_1.listPrompt)(en_1.lib.projects.create.prompt.distribution, {
32
+ choices: [
33
+ {
34
+ name: en_1.lib.projects.create.prompt.marketPlaceDistribution,
35
+ value: constants_1.marketplaceDistribution,
36
+ },
37
+ {
38
+ name: en_1.lib.projects.create.prompt.privateDistribution,
39
+ value: constants_1.privateDistribution,
40
+ },
41
+ ],
42
+ }));
43
+ if (distribution === constants_1.marketplaceDistribution) {
44
+ // This is the only valid auth type for marketplace
45
+ authType = constants_1.oAuth;
46
+ }
47
+ else {
48
+ authType =
49
+ providedAuth ||
50
+ (await (0, promptUtils_1.listPrompt)(en_1.lib.projects.create.prompt.auth, {
51
+ choices: [
52
+ { name: en_1.lib.projects.create.prompt.staticAuth, value: constants_1.staticAuth },
53
+ { name: en_1.lib.projects.create.prompt.oauth, value: constants_1.oAuth },
54
+ ],
55
+ }));
56
+ }
57
+ return {
58
+ distribution,
59
+ authType,
60
+ };
61
+ }
62
+ function calculateComponentTemplateChoices(components, authType, distribution, projectMetadata) {
63
+ const enabledComponents = [];
64
+ const disabledComponents = [];
65
+ components.forEach(template => {
66
+ const { supportedAuthTypes, supportedDistributions } = template;
67
+ const disabledReasons = [];
68
+ if (projectMetadata) {
69
+ const { count, maxCount } = projectMetadata.components[template.type];
70
+ if (count >= maxCount) {
71
+ disabledReasons.push(en_1.commands.project.add.error.maxExceeded(maxCount));
72
+ }
73
+ }
74
+ if (Array.isArray(supportedAuthTypes) &&
75
+ authType &&
76
+ !supportedAuthTypes.includes(authType)) {
77
+ disabledReasons.push(en_1.commands.project.add.error.authTypeNotAllowed(authType));
78
+ }
79
+ if (Array.isArray(supportedDistributions) &&
80
+ distribution &&
81
+ !supportedDistributions.includes(distribution)) {
82
+ disabledReasons.push(en_1.commands.project.add.error.distributionNotAllowed(distribution));
83
+ }
84
+ if (disabledReasons.length > 0) {
85
+ disabledComponents.push({
86
+ name: `[${chalk_1.default.yellow('DISABLED')}] ${template.label}`,
87
+ value: template,
88
+ disabled: disabledReasons.join(' '),
89
+ });
90
+ }
91
+ else {
92
+ enabledComponents.push({
93
+ name: template.label,
94
+ value: template,
95
+ });
96
+ }
97
+ });
98
+ return disabledComponents.length
99
+ ? [...enabledComponents, new inquirer.Separator(), ...disabledComponents]
100
+ : [...enabledComponents];
101
+ }
102
+ async function v3ComponentFlow(platformVersion, projectBase, providedAuth, providedDistribution) {
103
+ let repoConfig = undefined;
104
+ let authType;
105
+ let distribution;
106
+ try {
107
+ repoConfig = await (0, legacy_1.getConfigForPlatformVersion)(platformVersion);
108
+ }
109
+ catch (error) {
110
+ (0, errorHandlers_1.logError)(error);
111
+ return process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
112
+ }
113
+ const projectContentsChoice = projectBase ||
114
+ (await (0, promptUtils_1.listPrompt)(en_1.commands.project.create.prompts.parentComponents, {
115
+ choices: [
116
+ {
117
+ name: en_1.commands.project.create.prompts.emptyProject,
118
+ value: exports.EMPTY_PROJECT,
119
+ },
120
+ { name: en_1.commands.project.create.prompts.app, value: exports.PROJECT_WITH_APP },
121
+ ],
122
+ }));
123
+ if (projectContentsChoice === exports.PROJECT_WITH_APP) {
124
+ const { authType: selectedAuthType, distribution: selectedDistribution } = await createV3App(providedAuth, providedDistribution);
125
+ authType = selectedAuthType;
126
+ distribution = selectedDistribution;
127
+ }
128
+ const componentTemplateChoices = calculateComponentTemplateChoices(repoConfig?.components || [], authType, distribution);
129
+ return {
130
+ componentTemplateChoices,
131
+ authType,
132
+ distribution,
133
+ projectContents: projectContentsChoice,
134
+ repoConfig,
135
+ };
136
+ }
137
+ function generateComponentPaths({ createProjectPromptResponse, platformVersion, repoConfig, projectContents, authType, distribution, }) {
138
+ if (!(0, buildAndDeploy_1.useV3Api)(platformVersion)) {
139
+ return [];
140
+ }
141
+ const components = createProjectPromptResponse.componentTemplates?.map((componentTemplate) => {
142
+ return path_1.default.join(platformVersion, componentTemplate.path);
143
+ }) || [];
144
+ if (projectContents && projectContents !== exports.EMPTY_PROJECT) {
145
+ const parentComponent = repoConfig?.parentComponents?.find(possibleParent => {
146
+ return (possibleParent.type === projectContents &&
147
+ possibleParent.authType === authType &&
148
+ possibleParent.distribution === distribution);
149
+ });
150
+ if (parentComponent) {
151
+ components.push(path_1.default.join(platformVersion, parentComponent.path));
152
+ }
153
+ }
154
+ if (repoConfig?.defaultFiles) {
155
+ components.push(path_1.default.join(platformVersion, repoConfig?.defaultFiles));
156
+ }
157
+ return components;
158
+ }
@@ -1,4 +1,3 @@
1
- import { PublicApp } from '@hubspot/local-dev-lib/types/Apps';
2
1
  import { AppIRNode } from '../../../types/ProjectComponents';
3
2
  import LocalDevState from './LocalDevState';
4
3
  import LocalDevLogger from './LocalDevLogger';
@@ -10,14 +9,16 @@ declare class AppDevModeInterface {
10
9
  localDevState: LocalDevState;
11
10
  localDevLogger: LocalDevLogger;
12
11
  _appNode?: AppIRNode | null;
13
- appData?: PublicApp;
14
12
  marketplaceAppInstalls?: number;
15
13
  constructor(options: AppDevModeInterfaceConstructorOptions);
16
14
  private get appNode();
15
+ private get appData();
16
+ private set appData(value);
17
17
  private getAppInstallUrl;
18
18
  private fetchAppData;
19
19
  private checkMarketplaceAppInstalls;
20
20
  private checkTestAccountAppInstallation;
21
+ private setUpLocalDevServerMessageListeners;
21
22
  setup(args: any): Promise<void>;
22
23
  start(): Promise<void>;
23
24
  fileChange(filePath: string, event: string): Promise<void>;
@@ -18,7 +18,6 @@ class AppDevModeInterface {
18
18
  localDevState;
19
19
  localDevLogger;
20
20
  _appNode;
21
- appData;
22
21
  marketplaceAppInstalls;
23
22
  constructor(options) {
24
23
  this.localDevState = options.localDevState;
@@ -48,6 +47,18 @@ class AppDevModeInterface {
48
47
  }
49
48
  return this._appNode;
50
49
  }
50
+ get appData() {
51
+ if (!this.appNode) {
52
+ return undefined;
53
+ }
54
+ return this.localDevState.getAppDataByUid(this.appNode.uid);
55
+ }
56
+ set appData(appData) {
57
+ if (!this.appNode) {
58
+ return;
59
+ }
60
+ this.localDevState.setAppDataForUid(this.appNode.uid, appData);
61
+ }
51
62
  async getAppInstallUrl() {
52
63
  if (this.appNode?.config.auth.type === constants_1.APP_AUTH_TYPES.OAUTH) {
53
64
  return (0, urls_1.getOauthAppInstallUrl)({
@@ -77,7 +88,12 @@ class AppDevModeInterface {
77
88
  return;
78
89
  }
79
90
  const { data: { uniquePortalInstallCount }, } = await (0, appsDev_1.fetchPublicAppProductionInstallCounts)(appData.id, this.localDevState.targetProjectAccountId);
80
- this.appData = appData;
91
+ this.appData = {
92
+ id: appData.id,
93
+ clientId: appData.clientId,
94
+ name: appData.name,
95
+ installationState: constants_1.APP_INSTALLATION_STATES.NOT_INSTALLED,
96
+ };
81
97
  this.marketplaceAppInstalls = uniquePortalInstallCount;
82
98
  }
83
99
  async checkMarketplaceAppInstalls() {
@@ -98,19 +114,32 @@ class AppDevModeInterface {
98
114
  if (!this.appNode || !this.appData) {
99
115
  return;
100
116
  }
101
- // If the app is static auth, always prompt the user to install the app.
102
- // We are currently going this because we have no method to determine if the static auth app
103
- // is already installed in the portal
104
- if (this.appNode.config.auth.type === constants_1.APP_AUTH_TYPES.STATIC) {
105
- return (0, installAppPrompt_1.installAppPrompt)(await this.getAppInstallUrl(), false);
106
- }
107
117
  const { data: { isInstalledWithScopeGroups, previouslyAuthorizedScopeGroups }, } = await (0, localDevAuth_1.fetchAppInstallationData)(this.localDevState.targetTestingAccountId, this.localDevState.projectId, this.appNode.uid, this.appNode.config.auth.requiredScopes, this.appNode.config.auth.optionalScopes);
108
118
  const isReinstall = previouslyAuthorizedScopeGroups.length > 0;
119
+ if (isInstalledWithScopeGroups) {
120
+ this.appData = {
121
+ ...this.appData,
122
+ installationState: constants_1.APP_INSTALLATION_STATES.INSTALLED,
123
+ };
124
+ }
125
+ else if (isReinstall) {
126
+ this.appData = {
127
+ ...this.appData,
128
+ installationState: constants_1.APP_INSTALLATION_STATES.INSTALLED_WITH_OUTDATED_SCOPES,
129
+ };
130
+ }
109
131
  if (!isInstalledWithScopeGroups) {
110
132
  const installUrl = await this.getAppInstallUrl();
111
133
  await (0, installAppPrompt_1.installAppPrompt)(installUrl, isReinstall);
112
134
  }
113
135
  }
136
+ setUpLocalDevServerMessageListeners() {
137
+ this.localDevState.addListener('devServerMessage', message => {
138
+ if (message === constants_1.LOCAL_DEV_SERVER_MESSAGE_TYPES.WEBSOCKET_SERVER_CONNECTED) {
139
+ this.checkTestAccountAppInstallation();
140
+ }
141
+ });
142
+ }
114
143
  // @ts-expect-error TODO: reconcile types between CLI and UIE Dev Server
115
144
  // In the future, update UIE Dev Server to use LocalDevState
116
145
  async setup(args) {
@@ -127,6 +156,7 @@ class AppDevModeInterface {
127
156
  catch (e) {
128
157
  (0, index_1.logError)(e);
129
158
  }
159
+ this.setUpLocalDevServerMessageListeners();
130
160
  return ui_extensions_dev_server_1.DevModeUnifiedInterface.setup(args);
131
161
  }
132
162
  async start() {
@@ -1,27 +1,34 @@
1
1
  import { IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types';
2
2
  import LocalDevState from './LocalDevState';
3
3
  import LocalDevLogger from './LocalDevLogger';
4
- import { LocalDevStateConstructorOptions, LocalDevStateListener } from '../../../types/LocalDev';
4
+ import { LocalDevStateConstructorOptions, LocalDevStateListener, LocalDevServerMessage } from '../../../types/LocalDev';
5
5
  declare class LocalDevProcess {
6
6
  private state;
7
7
  private _logger;
8
8
  private devServerManager;
9
9
  constructor(options: LocalDevStateConstructorOptions);
10
10
  get projectDir(): string;
11
+ get projectId(): number;
12
+ get projectName(): string;
13
+ get targetProjectAccountId(): number;
14
+ get targetTestingAccountId(): number;
11
15
  get projectNodes(): {
12
16
  [key: string]: IntermediateRepresentationNodeLocalDev;
13
17
  };
14
18
  get logger(): LocalDevLogger;
19
+ get configFilesUpdatedSinceLastUpload(): Set<string>;
15
20
  private setupDevServers;
16
21
  private startDevServers;
17
22
  private cleanupDevServers;
18
23
  private compareLocalProjectToDeployed;
19
24
  private projectConfigValidForUpload;
20
- handleFileChange(filePath: string, event: string): void;
25
+ private updateProjectNodes;
26
+ handleFileChange(filePath: string, event: string): Promise<void>;
27
+ handleConfigFileChange(filePath: string, event: string): Promise<void>;
21
28
  start(): Promise<void>;
22
29
  stop(showProgress?: boolean): Promise<void>;
23
- updateProjectNodes(): Promise<void>;
24
- uploadProject(): Promise<void>;
25
- addStateListener<K extends keyof LocalDevState>(key: K, listener: LocalDevStateListener<K>): void;
30
+ uploadProject(): Promise<boolean>;
31
+ addStateListener<K extends keyof LocalDevState>(key: K, listener: LocalDevStateListener<K>, callOnInit?: boolean): void;
32
+ sendDevServerMessage(message: LocalDevServerMessage): void;
26
33
  }
27
34
  export default LocalDevProcess;
@@ -28,12 +28,27 @@ class LocalDevProcess {
28
28
  get projectDir() {
29
29
  return this.state.projectDir;
30
30
  }
31
+ get projectId() {
32
+ return this.state.projectId;
33
+ }
34
+ get projectName() {
35
+ return this.state.projectName;
36
+ }
37
+ get targetProjectAccountId() {
38
+ return this.state.targetProjectAccountId;
39
+ }
40
+ get targetTestingAccountId() {
41
+ return this.state.targetTestingAccountId;
42
+ }
31
43
  get projectNodes() {
32
44
  return this.state.projectNodes;
33
45
  }
34
46
  get logger() {
35
47
  return this._logger;
36
48
  }
49
+ get configFilesUpdatedSinceLastUpload() {
50
+ return this.state.configFilesUpdatedSinceLastUpload;
51
+ }
37
52
  async setupDevServers() {
38
53
  try {
39
54
  await this.devServerManager.setup();
@@ -90,7 +105,19 @@ class LocalDevProcess {
90
105
  });
91
106
  return true;
92
107
  }
93
- handleFileChange(filePath, event) {
108
+ async updateProjectNodes() {
109
+ const intermediateRepresentation = await (0, project_parsing_lib_1.translateForLocalDev)({
110
+ projectSourceDir: path_1.default.join(this.state.projectDir, this.state.projectConfig.srcDir),
111
+ platformVersion: this.state.projectConfig.platformVersion,
112
+ accountId: this.state.targetProjectAccountId,
113
+ }, {
114
+ configFilesUpdatedSinceLastUpload: this.state.configFilesUpdatedSinceLastUpload,
115
+ });
116
+ this.state.projectNodes =
117
+ intermediateRepresentation.intermediateNodesIndexedByUid;
118
+ }
119
+ async handleFileChange(filePath, event) {
120
+ await this.updateProjectNodes();
94
121
  try {
95
122
  this.devServerManager.fileChange({ filePath, event });
96
123
  }
@@ -98,6 +125,13 @@ class LocalDevProcess {
98
125
  this.logger.fileChangeError(e);
99
126
  }
100
127
  }
128
+ async handleConfigFileChange(filePath, event) {
129
+ if (event === 'add' || event === 'change') {
130
+ this.state.addUpdatedConfigFileUpdatedSinceLastUpload(filePath);
131
+ }
132
+ await this.updateProjectNodes();
133
+ this.logger.uploadWarning();
134
+ }
101
135
  async start() {
102
136
  this.logger.resetSpinnies();
103
137
  // Local dev currently relies on the existence of a deployed build in the target account
@@ -132,21 +166,12 @@ class LocalDevProcess {
132
166
  }
133
167
  process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
134
168
  }
135
- async updateProjectNodes() {
136
- const intermediateRepresentation = await (0, project_parsing_lib_1.translateForLocalDev)({
137
- projectSourceDir: path_1.default.join(this.state.projectDir, this.state.projectConfig.srcDir),
138
- platformVersion: this.state.projectConfig.platformVersion,
139
- accountId: this.state.targetProjectAccountId,
140
- });
141
- this.state.projectNodes =
142
- intermediateRepresentation.intermediateNodesIndexedByUid;
143
- }
144
169
  async uploadProject() {
145
170
  this.logger.uploadInitiated();
146
171
  const isUploadable = await this.projectConfigValidForUpload();
147
172
  if (!isUploadable) {
148
173
  this.logger.projectConfigMismatch();
149
- return;
174
+ return false;
150
175
  }
151
176
  const { uploadError } = await (0, upload_1.handleProjectUpload)({
152
177
  accountId: this.state.targetProjectAccountId,
@@ -158,14 +183,19 @@ class LocalDevProcess {
158
183
  });
159
184
  if (uploadError) {
160
185
  this.logger.uploadError(uploadError);
186
+ return false;
161
187
  }
162
- else {
163
- this.logger.uploadSuccess();
164
- this.logger.clearUploadWarnings();
165
- }
188
+ this.state.resetConfigFilesUpdatedSinceLastUpload();
189
+ this.updateProjectNodes();
190
+ this.logger.uploadSuccess();
191
+ this.logger.clearUploadWarnings();
192
+ return true;
193
+ }
194
+ addStateListener(key, listener, callOnInit = false) {
195
+ this.state.addListener(key, listener, callOnInit);
166
196
  }
167
- addStateListener(key, listener) {
168
- this.state.addListener(key, listener);
197
+ sendDevServerMessage(message) {
198
+ this.state.devServerMessage = message;
169
199
  }
170
200
  }
171
201
  exports.default = LocalDevProcess;
@@ -2,26 +2,31 @@ import { Build } from '@hubspot/local-dev-lib/types/Build';
2
2
  import { IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types';
3
3
  import { Environment } from '@hubspot/local-dev-lib/types/Config';
4
4
  import { ProjectConfig } from '../../../types/Projects';
5
- import { LocalDevStateConstructorOptions, LocalDevStateListener } from '../../../types/LocalDev';
5
+ import { LocalDevStateConstructorOptions, LocalDevStateListener, AppLocalDevData, LocalDevServerMessage } from '../../../types/LocalDev';
6
6
  declare class LocalDevState {
7
7
  private _targetProjectAccountId;
8
8
  private _targetTestingAccountId;
9
9
  private _projectConfig;
10
10
  private _projectDir;
11
11
  private _projectId;
12
+ private _projectName;
12
13
  private _debug;
13
14
  private _deployedBuild?;
14
15
  private _isGithubLinked;
15
16
  private _projectNodes;
16
17
  private _env;
17
18
  private _listeners;
18
- constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectId, debug, deployedBuild, isGithubLinked, initialProjectNodes, env, }: LocalDevStateConstructorOptions);
19
+ private _configFilesUpdatedSinceLastUpload;
20
+ private _appData;
21
+ private _devServerMessage;
22
+ constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectId, projectName, debug, deployedBuild, isGithubLinked, initialProjectNodes, env, }: LocalDevStateConstructorOptions);
19
23
  private runListeners;
20
24
  get targetProjectAccountId(): number;
21
25
  get targetTestingAccountId(): number;
22
26
  get projectConfig(): ProjectConfig;
23
27
  get projectDir(): string;
24
28
  get projectId(): number;
29
+ get projectName(): string;
25
30
  get debug(): boolean;
26
31
  get deployedBuild(): Build | undefined;
27
32
  get isGithubLinked(): boolean;
@@ -32,6 +37,14 @@ declare class LocalDevState {
32
37
  [key: string]: IntermediateRepresentationNodeLocalDev;
33
38
  });
34
39
  get env(): Environment;
35
- addListener<K extends keyof LocalDevState>(key: K, listener: LocalDevStateListener<K>): void;
40
+ get configFilesUpdatedSinceLastUpload(): Set<string>;
41
+ addUpdatedConfigFileUpdatedSinceLastUpload(filePath: string): void;
42
+ resetConfigFilesUpdatedSinceLastUpload(): void;
43
+ get appData(): Record<string, AppLocalDevData>;
44
+ getAppDataByUid(uid: string): AppLocalDevData | undefined;
45
+ setAppDataForUid(uid: string, appData: AppLocalDevData): void;
46
+ get devServerMessage(): string;
47
+ set devServerMessage(message: LocalDevServerMessage);
48
+ addListener<K extends keyof LocalDevState>(key: K, listener: LocalDevStateListener<K>, callOnInit?: boolean): void;
36
49
  }
37
50
  export default LocalDevState;
@@ -1,28 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const constants_1 = require("../../constants");
3
4
  class LocalDevState {
4
5
  _targetProjectAccountId;
5
6
  _targetTestingAccountId;
6
7
  _projectConfig;
7
8
  _projectDir;
8
9
  _projectId;
10
+ _projectName;
9
11
  _debug;
10
12
  _deployedBuild;
11
13
  _isGithubLinked;
12
14
  _projectNodes;
13
15
  _env;
14
16
  _listeners;
15
- constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectId, debug, deployedBuild, isGithubLinked, initialProjectNodes, env, }) {
17
+ _configFilesUpdatedSinceLastUpload;
18
+ _appData;
19
+ _devServerMessage;
20
+ constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectId, projectName, debug, deployedBuild, isGithubLinked, initialProjectNodes, env, }) {
16
21
  this._targetProjectAccountId = targetProjectAccountId;
17
22
  this._targetTestingAccountId = targetTestingAccountId;
18
23
  this._projectConfig = projectConfig;
19
24
  this._projectDir = projectDir;
20
25
  this._projectId = projectId;
26
+ this._projectName = projectName;
21
27
  this._debug = debug || false;
22
28
  this._deployedBuild = deployedBuild;
23
29
  this._isGithubLinked = isGithubLinked;
24
30
  this._projectNodes = initialProjectNodes;
25
31
  this._env = env;
32
+ this._configFilesUpdatedSinceLastUpload = new Set();
33
+ this._appData = {};
34
+ this._devServerMessage = constants_1.LOCAL_DEV_SERVER_MESSAGE_TYPES.INITIAL;
26
35
  this._listeners = {};
27
36
  }
28
37
  runListeners(key) {
@@ -47,6 +56,9 @@ class LocalDevState {
47
56
  get projectId() {
48
57
  return this._projectId;
49
58
  }
59
+ get projectName() {
60
+ return this._projectName;
61
+ }
50
62
  get debug() {
51
63
  return this._debug;
52
64
  }
@@ -68,11 +80,40 @@ class LocalDevState {
68
80
  get env() {
69
81
  return this._env;
70
82
  }
71
- addListener(key, listener) {
83
+ get configFilesUpdatedSinceLastUpload() {
84
+ return this._configFilesUpdatedSinceLastUpload;
85
+ }
86
+ addUpdatedConfigFileUpdatedSinceLastUpload(filePath) {
87
+ this._configFilesUpdatedSinceLastUpload.add(filePath);
88
+ }
89
+ resetConfigFilesUpdatedSinceLastUpload() {
90
+ this._configFilesUpdatedSinceLastUpload.clear();
91
+ }
92
+ get appData() {
93
+ return { ...this._appData };
94
+ }
95
+ getAppDataByUid(uid) {
96
+ return { ...this._appData[uid] };
97
+ }
98
+ setAppDataForUid(uid, appData) {
99
+ this._appData[uid] = appData;
100
+ this.runListeners('appData');
101
+ }
102
+ get devServerMessage() {
103
+ return this._devServerMessage;
104
+ }
105
+ set devServerMessage(message) {
106
+ this._devServerMessage = message;
107
+ this.runListeners('devServerMessage');
108
+ }
109
+ addListener(key, listener, callOnInit = false) {
72
110
  if (!this._listeners[key]) {
73
111
  this._listeners[key] = [];
74
112
  }
75
113
  this._listeners[key].push(listener);
114
+ if (callOnInit) {
115
+ listener(this[key]);
116
+ }
76
117
  }
77
118
  }
78
119
  exports.default = LocalDevState;
@@ -19,14 +19,11 @@ class LocalDevWatcher {
19
19
  this.localDevProcess = localDevProcess;
20
20
  this.watcher = null;
21
21
  }
22
- async handleWatchEvent(filePath, event, configPaths) {
23
- await this.localDevProcess.updateProjectNodes();
22
+ handleWatchEvent(filePath, event, configPaths) {
24
23
  if (configPaths.includes(filePath)) {
25
- this.localDevProcess.logger.uploadWarning();
26
- }
27
- else {
28
- this.localDevProcess.handleFileChange(filePath, event);
24
+ return this.localDevProcess.handleConfigFileChange(filePath, event);
29
25
  }
26
+ return this.localDevProcess.handleFileChange(filePath, event);
30
27
  }
31
28
  start() {
32
29
  this.watcher = chokidar_1.default.watch(this.localDevProcess.projectDir, {
@@ -4,12 +4,15 @@ declare class LocalDevWebsocketServer {
4
4
  private _websocket?;
5
5
  private debug?;
6
6
  private localDevProcess;
7
+ private ALLOWED_ORIGINS;
7
8
  constructor(localDevProcess: LocalDevProcess, debug?: boolean);
8
9
  private websocket;
9
10
  private log;
10
11
  private logError;
11
12
  private sendMessage;
13
+ private handleUpload;
12
14
  private setupMessageHandlers;
15
+ private sendProjectData;
13
16
  private setupStateListeners;
14
17
  start(): Promise<void>;
15
18
  shutdown(): void;