@hubspot/cli 7.6.2 → 7.7.0-beta.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 (33) hide show
  1. package/commands/config/set.d.ts +1 -1
  2. package/commands/config/set.js +65 -33
  3. package/commands/init.js +0 -1
  4. package/commands/project/__tests__/validate.test.d.ts +1 -0
  5. package/commands/project/__tests__/validate.test.js +98 -0
  6. package/commands/project/validate.js +4 -4
  7. package/commands/testAccount/__tests__/delete.test.js +2 -4
  8. package/commands/testAccount/delete.d.ts +4 -3
  9. package/commands/testAccount/delete.js +155 -14
  10. package/lang/en.d.ts +37 -8
  11. package/lang/en.js +49 -20
  12. package/lib/__tests__/yargsUtils.test.js +83 -9
  13. package/lib/configOptions.js +7 -0
  14. package/lib/constants.d.ts +6 -0
  15. package/lib/constants.js +10 -0
  16. package/lib/doctor/DiagnosticInfoBuilder.js +7 -6
  17. package/lib/projects/__tests__/AppDevModeInterface.test.js +2 -0
  18. package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +64 -33
  19. package/lib/projects/__tests__/localDevProjectHelpers.test.js +2 -0
  20. package/lib/projects/__tests__/upload.test.d.ts +1 -0
  21. package/lib/projects/__tests__/upload.test.js +82 -0
  22. package/lib/projects/localDev/AppDevModeInterface.d.ts +2 -0
  23. package/lib/projects/localDev/AppDevModeInterface.js +17 -8
  24. package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +0 -1
  25. package/lib/projects/localDev/LocalDevWebsocketServer.js +4 -7
  26. package/lib/projects/structure.js +4 -4
  27. package/lib/projects/upload.d.ts +1 -1
  28. package/lib/projects/upload.js +15 -6
  29. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +10 -1
  30. package/lib/prompts/promptUtils.js +8 -5
  31. package/lib/yargsUtils.d.ts +1 -1
  32. package/lib/yargsUtils.js +12 -5
  33. package/package.json +2 -2
@@ -10,16 +10,13 @@ import pkg from '../../../package.json' with { type: 'json' };
10
10
  const SERVER_INSTANCE_ID = 'local-dev-ui-websocket-server';
11
11
  const LOCAL_DEV_WEBSOCKET_SERVER_VERSION = 1;
12
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('|')})$`);
13
16
  class LocalDevWebsocketServer {
14
17
  server;
15
18
  debug;
16
19
  localDevProcess;
17
- ALLOWED_ORIGINS = [
18
- 'https://app.hubspot.com',
19
- 'https://app.hubspotqa.com',
20
- 'https://local.hubspot.com',
21
- 'https://local.hubspotqa.com',
22
- ];
23
20
  constructor(localDevProcess, debug) {
24
21
  this.localDevProcess = localDevProcess;
25
22
  this.debug = debug;
@@ -166,7 +163,7 @@ class LocalDevWebsocketServer {
166
163
  this.log(lib.LocalDevWebsocketServer.logs.startup(port));
167
164
  this.server.on('connection', (ws, req) => {
168
165
  const origin = req.headers.origin;
169
- if (!origin || !this.ALLOWED_ORIGINS.includes(origin)) {
166
+ if (!origin || !ALLOWED_ORIGIN_REGEX.test(origin)) {
170
167
  ws.close(1008, lib.LocalDevWebsocketServer.errors.originNotAllowed(origin));
171
168
  return;
172
169
  }
@@ -4,11 +4,11 @@ import { walk } from '@hubspot/local-dev-lib/fs';
4
4
  import { logger } from '@hubspot/local-dev-lib/logger';
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]: 'app.json',
10
- [ComponentTypes.PublicApp]: 'public-app.json',
11
- [ComponentTypes.HublTheme]: 'theme.json',
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;
@@ -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 {};
@@ -15,6 +15,8 @@ import { uiLogger } from '../ui/logger.js';
15
15
  import { useV3Api } 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
- logError(e);
74
- process.exit(EXIT_CODES.ERROR);
75
+ resolve({ uploadError: e });
75
76
  }
76
77
  }
77
78
  await ensureProjectExists(accountId, projectConfig.name, {
@@ -105,11 +106,19 @@ 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 filenames = fs.readdirSync(srcDir);
110
- if (!filenames || filenames.length === 0) {
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 (useV3Api(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);
@@ -94,7 +94,16 @@ export async function createDeveloperTestAccountConfigPrompt(args = {}, supportF
94
94
  },
95
95
  ],
96
96
  });
97
- if (useDefaultAccountLevelsPromptResult.useDefaultAccountLevels === 'manual') {
97
+ if (useDefaultAccountLevelsPromptResult.useDefaultAccountLevels === 'default') {
98
+ accountLevelsArray = [
99
+ { hub: 'MARKETING', tier: AccountTiers.ENTERPRISE },
100
+ { hub: 'OPS', tier: AccountTiers.ENTERPRISE },
101
+ { hub: 'SERVICE', tier: AccountTiers.ENTERPRISE },
102
+ { hub: 'SALES', tier: AccountTiers.ENTERPRISE },
103
+ { hub: 'CONTENT', tier: AccountTiers.ENTERPRISE },
104
+ ];
105
+ }
106
+ else {
98
107
  const accountLevelsPromptResult = await promptUser({
99
108
  name: 'testAccountLevels',
100
109
  message: lib.prompts.createDeveloperTestAccountConfigPrompt.tiersPrompt,
@@ -139,8 +139,10 @@ function handleCheckboxPrompt(config) {
139
139
  }).then(resp => ({ [config.name]: resp }));
140
140
  }
141
141
  function handleConfirmPrompt(config) {
142
- return confirmPrompt(config.message, {
143
- defaultAnswer: config.default,
142
+ return confirm({
143
+ message: config.message,
144
+ default: config.default,
145
+ theme: PROMPT_THEME,
144
146
  }).then(resp => ({ [config.name]: resp }));
145
147
  }
146
148
  function handleInputPrompt(config) {
@@ -165,12 +167,13 @@ function handleSelectPrompt(config) {
165
167
  }
166
168
  export async function confirmPrompt(message, options = {}) {
167
169
  const { defaultAnswer = true } = options;
168
- const choice = await confirm({
170
+ const { confirm: result } = await promptUser({
171
+ name: 'confirm',
172
+ type: 'confirm',
169
173
  message,
170
174
  default: defaultAnswer,
171
- theme: PROMPT_THEME,
172
175
  });
173
- return choice;
176
+ return result;
174
177
  }
175
178
  export async function listPrompt(message, { choices, when, defaultAnswer, validate, loop, }) {
176
179
  const { choice } = await promptUser({
@@ -13,4 +13,4 @@ export declare function makeYargsBuilder<T>(callback: (yargs: Argv) => Argv<T>,
13
13
  };
14
14
  useJSONOutputOptions?: boolean;
15
15
  }): (yargs: Argv) => Promise<Argv<T>>;
16
- export declare function getExclusiveConflicts(options: string[]): Record<string, string[]>;
16
+ export declare function strictEnforceBoolean(rawArgs: string[], booleanOptions: string[]): boolean;
package/lib/yargsUtils.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { addCustomHelpOutput, addTestingOptions, addAccountOptions, addConfigOptions, addGlobalOptions, addUseEnvironmentOptions, addCmsPublishModeOptions, addJSONOutputOptions, } from './commonOpts.js';
2
2
  import { hasFlag } from './utils/hasFlag.js';
3
+ import { commands } from '../lang/en.js';
3
4
  // Re-export for backwards compatibility
4
5
  export { hasFlag };
5
6
  export function makeYargsBuilder(callback, command, describe, options = {}) {
@@ -34,9 +35,15 @@ export function makeYargsBuilder(callback, command, describe, options = {}) {
34
35
  return result;
35
36
  };
36
37
  }
37
- export function getExclusiveConflicts(options) {
38
- return options.reduce((acc, curr) => {
39
- acc[curr] = options.filter(s => s !== curr);
40
- return acc;
41
- }, {});
38
+ export function strictEnforceBoolean(rawArgs, booleanOptions) {
39
+ for (const option of booleanOptions) {
40
+ const argIndex = rawArgs.findIndex(arg => arg.startsWith(`--${option}=`));
41
+ if (argIndex !== -1) {
42
+ const value = rawArgs[argIndex].split('=')[1];
43
+ if (value && !['true', 'false'].includes(value.toLowerCase())) {
44
+ throw new Error(commands.config.subcommands.set.errors.invalidBoolean(option, value));
45
+ }
46
+ }
47
+ }
48
+ return true;
42
49
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "7.6.2",
3
+ "version": "7.7.0-beta.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": "3.19.1",
10
- "@hubspot/project-parsing-lib": "0.8.6",
10
+ "@hubspot/project-parsing-lib": "0.9.0",
11
11
  "@hubspot/serverless-dev-runtime": "7.0.6",
12
12
  "@hubspot/theme-preview-dev-server": "0.0.10",
13
13
  "@hubspot/ui-extensions-dev-server": "0.10.0",