@hubspot/cli 7.3.0 → 7.4.0-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.
package/bin/cli.js CHANGED
@@ -43,6 +43,7 @@ const cmsCommand = require('../commands/cms');
43
43
  const feedbackCommand = require('../commands/feedback');
44
44
  const doctorCommand = require('../commands/doctor');
45
45
  const completionCommand = require('../commands/completion');
46
+ const appCommand = require('../commands/app');
46
47
  const notifier = updateNotifier({
47
48
  pkg: { ...pkg, name: '@hubspot/cli' },
48
49
  distTag: 'latest',
@@ -294,6 +295,7 @@ const argv = yargs
294
295
  .command(feedbackCommand)
295
296
  .command(doctorCommand)
296
297
  .command(completionCommand)
298
+ .command(appCommand)
297
299
  .help()
298
300
  .alias('h', 'help')
299
301
  .recommendCommands()
@@ -0,0 +1,7 @@
1
+ import { ArgumentsCamelCase, Argv, CommandModule } from 'yargs';
2
+ import { MigrateAppOptions } from '../../types/Yargs';
3
+ export declare const validMigrationTargets: string[];
4
+ export declare function handler(options: ArgumentsCamelCase<MigrateAppOptions>): Promise<never>;
5
+ export declare function builder(yargs: Argv): Argv<MigrateAppOptions>;
6
+ declare const migrateCommand: CommandModule<unknown, MigrateAppOptions>;
7
+ export default migrateCommand;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validMigrationTargets = void 0;
4
+ exports.handler = handler;
5
+ exports.builder = builder;
6
+ const commonOpts_1 = require("../../lib/commonOpts");
7
+ const usageTracking_1 = require("../../lib/usageTracking");
8
+ const lang_1 = require("../../lib/lang");
9
+ const errorHandlers_1 = require("../../lib/errorHandlers");
10
+ const exitCodes_1 = require("../../lib/enums/exitCodes");
11
+ const config_1 = require("@hubspot/local-dev-lib/config");
12
+ const migrate_1 = require("../../lib/app/migrate");
13
+ const projects_1 = require("@hubspot/local-dev-lib/constants/projects");
14
+ const logger_1 = require("@hubspot/local-dev-lib/logger");
15
+ const ui_1 = require("../../lib/ui");
16
+ const { v2023_2, v2025_2, unstable } = projects_1.PLATFORM_VERSIONS;
17
+ exports.validMigrationTargets = [v2023_2, v2025_2, unstable];
18
+ const command = 'migrate';
19
+ const describe = undefined; // uiBetaTag(i18n(`commands.project.subcommands.migrateApp.header.text.describe`), false);
20
+ async function handler(options) {
21
+ const { derivedAccountId, platformVersion } = options;
22
+ await (0, usageTracking_1.trackCommandUsage)('migrate-app', {}, derivedAccountId);
23
+ const accountConfig = (0, config_1.getAccountConfig)(derivedAccountId);
24
+ if (!accountConfig) {
25
+ logger_1.logger.error((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.errors.noAccountConfig`));
26
+ return process.exit(exitCodes_1.EXIT_CODES.ERROR);
27
+ }
28
+ logger_1.logger.log('');
29
+ logger_1.logger.log((0, ui_1.uiBetaTag)((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.header.text`), false));
30
+ logger_1.logger.log((0, ui_1.uiLink)((0, lang_1.i18n)(`commands.project.subcommands.migrateApp.header.link`), 'https://developers.hubspot.com/docs/platform/migrate-a-public-app-to-projects'));
31
+ logger_1.logger.log('');
32
+ try {
33
+ if (platformVersion === v2025_2 || platformVersion === unstable) {
34
+ await (0, migrate_1.migrateApp2025_2)(derivedAccountId, options);
35
+ }
36
+ else {
37
+ await (0, migrate_1.migrateApp2023_2)(derivedAccountId, options, accountConfig);
38
+ }
39
+ }
40
+ catch (error) {
41
+ if (error &&
42
+ typeof error === 'object' &&
43
+ 'errors' in error &&
44
+ Array.isArray(error.errors)) {
45
+ error.errors.forEach(err => (0, errorHandlers_1.logError)(err));
46
+ }
47
+ else {
48
+ (0, errorHandlers_1.logError)(error, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId }));
49
+ }
50
+ await (0, usageTracking_1.trackCommandMetadataUsage)('migrate-app', { successful: false }, derivedAccountId);
51
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
52
+ }
53
+ await (0, usageTracking_1.trackCommandMetadataUsage)('migrate-app', { successful: true }, derivedAccountId);
54
+ return process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
55
+ }
56
+ function builder(yargs) {
57
+ (0, commonOpts_1.addConfigOptions)(yargs);
58
+ (0, commonOpts_1.addAccountOptions)(yargs);
59
+ (0, commonOpts_1.addUseEnvironmentOptions)(yargs);
60
+ yargs.options({
61
+ name: {
62
+ describe: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.options.name.describe`),
63
+ type: 'string',
64
+ },
65
+ dest: {
66
+ describe: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.options.dest.describe`),
67
+ type: 'string',
68
+ },
69
+ 'app-id': {
70
+ describe: (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.options.appId.describe`),
71
+ type: 'number',
72
+ },
73
+ 'platform-version': {
74
+ type: 'string',
75
+ choices: exports.validMigrationTargets,
76
+ hidden: true,
77
+ default: '2023.2',
78
+ },
79
+ });
80
+ yargs.example([
81
+ [
82
+ `$0 app migrate`,
83
+ (0, lang_1.i18n)(`commands.project.subcommands.migrateApp.examples.default`),
84
+ ],
85
+ ]);
86
+ return yargs;
87
+ }
88
+ const migrateCommand = {
89
+ command,
90
+ describe,
91
+ handler,
92
+ builder,
93
+ };
94
+ exports.default = migrateCommand;
@@ -0,0 +1,6 @@
1
+ import { Argv, CommandModule } from 'yargs';
2
+ export declare const command: string[];
3
+ export declare const describe: undefined;
4
+ export declare function builder(yargs: Argv): Argv<{}>;
5
+ declare const appCommand: CommandModule;
6
+ export default appCommand;
@@ -0,0 +1,23 @@
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.describe = exports.command = void 0;
7
+ exports.builder = builder;
8
+ const migrate_1 = __importDefault(require("./app/migrate"));
9
+ const commonOpts_1 = require("../lib/commonOpts");
10
+ exports.command = ['app', 'apps'];
11
+ // Keep the command hidden for now
12
+ exports.describe = undefined;
13
+ function builder(yargs) {
14
+ (0, commonOpts_1.addGlobalOptions)(yargs);
15
+ return yargs.command(migrate_1.default).demandCommand(1, '');
16
+ }
17
+ const appCommand = {
18
+ command: exports.command,
19
+ describe: exports.describe,
20
+ builder,
21
+ handler: () => { },
22
+ };
23
+ exports.default = appCommand;
@@ -1 +1,9 @@
1
- export {};
1
+ import { ArgumentsCamelCase, Argv, CommandModule } from 'yargs';
2
+ import { CloneAppArgs } from '../../types/Yargs';
3
+ export declare const command = "clone-app";
4
+ export declare const describe: string | undefined;
5
+ export declare const deprecated = true;
6
+ export declare const handler: (options: ArgumentsCamelCase<CloneAppArgs>) => Promise<never>;
7
+ export declare const builder: (yargs: Argv) => Argv<CloneAppArgs>;
8
+ declare const cloneAppCommand: CommandModule<unknown, CloneAppArgs>;
9
+ export default cloneAppCommand;
@@ -1,43 +1,46 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- // @ts-nocheck
4
- const path = require('path');
5
- const fs = require('fs');
6
- const { addAccountOptions, addConfigOptions, addUseEnvironmentOptions, } = require('../../lib/commonOpts');
7
- const { trackCommandUsage, trackCommandMetadataUsage, } = require('../../lib/usageTracking');
8
- const { i18n } = require('../../lib/lang');
9
- const { selectPublicAppPrompt, } = require('../../lib/prompts/selectPublicAppPrompt');
10
- const { createProjectPrompt, } = require('../../lib/prompts/createProjectPrompt');
11
- const { poll } = require('../../lib/polling');
12
- const { uiBetaTag, uiLine, uiCommandReference, uiAccountDescription, } = require('../../lib/ui');
13
- const SpinniesManager = require('../../lib/ui/SpinniesManager');
14
- const { logError, ApiErrorContext } = require('../../lib/errorHandlers/index');
15
- const { EXIT_CODES } = require('../../lib/enums/exitCodes');
16
- const { isAppDeveloperAccount } = require('../../lib/accountTypes');
17
- const { writeProjectConfig } = require('../../lib/projects');
18
- const { PROJECT_CONFIG_FILE } = require('../../lib/constants');
19
- const { cloneApp, checkCloneStatus, downloadClonedProject, } = require('@hubspot/local-dev-lib/api/projects');
20
- const { getCwd, sanitizeFileName } = require('@hubspot/local-dev-lib/path');
21
- const { logger } = require('@hubspot/local-dev-lib/logger');
22
- const { getAccountConfig } = require('@hubspot/local-dev-lib/config');
23
- const { extractZipArchive } = require('@hubspot/local-dev-lib/archive');
6
+ exports.builder = exports.handler = exports.deprecated = exports.describe = exports.command = void 0;
7
+ const ui_1 = require("../../lib/ui");
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const commonOpts_1 = require("../../lib/commonOpts");
11
+ const usageTracking_1 = require("../../lib/usageTracking");
12
+ const lang_1 = require("../../lib/lang");
13
+ const selectPublicAppPrompt_1 = require("../../lib/prompts/selectPublicAppPrompt");
14
+ const createProjectPrompt_1 = require("../../lib/prompts/createProjectPrompt");
15
+ const polling_1 = require("../../lib/polling");
16
+ const ui_2 = require("../../lib/ui");
17
+ const errorHandlers_1 = require("../../lib/errorHandlers");
18
+ const exitCodes_1 = require("../../lib/enums/exitCodes");
19
+ const accountTypes_1 = require("../../lib/accountTypes");
20
+ const projects_1 = require("../../lib/projects");
21
+ const constants_1 = require("../../lib/constants");
22
+ const projects_2 = require("@hubspot/local-dev-lib/api/projects");
23
+ const path_2 = require("@hubspot/local-dev-lib/path");
24
+ const logger_1 = require("@hubspot/local-dev-lib/logger");
25
+ const archive_1 = require("@hubspot/local-dev-lib/archive");
26
+ const config_1 = require("@hubspot/local-dev-lib/config");
27
+ const SpinniesManager_1 = __importDefault(require("../../lib/ui/SpinniesManager"));
28
+ const migrate_1 = require("../../lib/app/migrate");
24
29
  const i18nKey = 'commands.project.subcommands.cloneApp';
25
30
  exports.command = 'clone-app';
26
- exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
27
- exports.handler = async (options) => {
31
+ exports.describe = (0, ui_1.uiDeprecatedTag)((0, lang_1.i18n)(`${i18nKey}.describe`), false);
32
+ exports.deprecated = true;
33
+ const handler = async (options) => {
28
34
  const { derivedAccountId } = options;
29
- const accountConfig = getAccountConfig(derivedAccountId);
30
- const accountName = uiAccountDescription(derivedAccountId);
31
- trackCommandUsage('clone-app', {}, derivedAccountId);
32
- if (!isAppDeveloperAccount(accountConfig)) {
33
- uiLine();
34
- logger.error(i18n(`${i18nKey}.errors.invalidAccountTypeTitle`));
35
- logger.log(i18n(`${i18nKey}.errors.invalidAccountTypeDescription`, {
36
- useCommand: uiCommandReference('hs accounts use'),
37
- authCommand: uiCommandReference('hs auth'),
38
- }));
39
- uiLine();
40
- process.exit(EXIT_CODES.SUCCESS);
35
+ await (0, usageTracking_1.trackCommandUsage)('clone-app', {}, derivedAccountId);
36
+ const accountConfig = (0, config_1.getAccountConfig)(derivedAccountId);
37
+ const accountName = (0, ui_2.uiAccountDescription)(derivedAccountId);
38
+ if (!accountConfig) {
39
+ throw new Error((0, lang_1.i18n)(`commands.projects.subcommands.cloneApp.errors.noAccountConfig`));
40
+ }
41
+ if (!(0, accountTypes_1.isAppDeveloperAccount)(accountConfig)) {
42
+ (0, migrate_1.logInvalidAccountError)(i18nKey);
43
+ process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
41
44
  }
42
45
  let appId;
43
46
  let projectName;
@@ -45,96 +48,108 @@ exports.handler = async (options) => {
45
48
  try {
46
49
  appId = options.appId;
47
50
  if (!appId) {
48
- const appIdResponse = await selectPublicAppPrompt({
51
+ const appIdResponse = await (0, selectPublicAppPrompt_1.selectPublicAppPrompt)({
49
52
  accountId: derivedAccountId,
50
53
  accountName,
51
- options,
52
54
  isMigratingApp: false,
53
55
  });
54
56
  appId = appIdResponse.appId;
55
57
  }
56
- const createProjectPromptResponse = await createProjectPrompt(options);
58
+ const createProjectPromptResponse = await (0, createProjectPrompt_1.createProjectPrompt)(options);
57
59
  projectName = createProjectPromptResponse.name;
58
60
  projectDest = createProjectPromptResponse.dest;
59
61
  }
60
62
  catch (error) {
61
- logError(error, new ApiErrorContext({ accountId: derivedAccountId }));
62
- process.exit(EXIT_CODES.ERROR);
63
+ (0, errorHandlers_1.logError)(error, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId }));
64
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
63
65
  }
64
- await trackCommandMetadataUsage('clone-app', { status: 'STARTED' }, derivedAccountId);
66
+ await (0, usageTracking_1.trackCommandMetadataUsage)('clone-app', { step: 'STARTED' }, derivedAccountId);
65
67
  try {
66
- SpinniesManager.init();
67
- SpinniesManager.add('cloneApp', {
68
- text: i18n(`${i18nKey}.cloneStatus.inProgress`),
68
+ SpinniesManager_1.default.init();
69
+ SpinniesManager_1.default.add('cloneApp', {
70
+ text: (0, lang_1.i18n)(`${i18nKey}.cloneStatus.inProgress`),
69
71
  });
70
- const { data: { exportId }, } = await cloneApp(derivedAccountId, appId);
71
- const { status } = await poll(() => checkCloneStatus(derivedAccountId, exportId));
72
+ const { data: { exportId }, } = await (0, projects_2.cloneApp)(derivedAccountId, appId);
73
+ const { status } = await (0, polling_1.poll)(() => (0, projects_2.checkCloneStatus)(derivedAccountId, exportId));
72
74
  if (status === 'SUCCESS') {
73
75
  // Ensure correct project folder structure exists
74
- const baseDestPath = path.resolve(getCwd(), projectDest);
75
- const absoluteDestPath = path.resolve(baseDestPath, 'src', 'app');
76
- fs.mkdirSync(absoluteDestPath, { recursive: true });
76
+ const baseDestPath = path_1.default.resolve((0, path_2.getCwd)(), projectDest);
77
+ const absoluteDestPath = path_1.default.resolve(baseDestPath, 'src', 'app');
78
+ fs_1.default.mkdirSync(absoluteDestPath, { recursive: true });
77
79
  // Extract zipped app files and place them in correct directory
78
- const { data: zippedApp } = await downloadClonedProject(derivedAccountId, exportId);
79
- await extractZipArchive(zippedApp, sanitizeFileName(projectName), absoluteDestPath, {
80
+ const { data: zippedApp } = await (0, projects_2.downloadClonedProject)(derivedAccountId, exportId);
81
+ await (0, archive_1.extractZipArchive)(zippedApp, (0, path_2.sanitizeFileName)(projectName), absoluteDestPath, {
80
82
  includesRootDir: true,
81
83
  hideLogs: true,
82
84
  });
83
85
  // Create hsproject.json file
84
- const configPath = path.join(baseDestPath, PROJECT_CONFIG_FILE);
86
+ const configPath = path_1.default.join(baseDestPath, constants_1.PROJECT_CONFIG_FILE);
85
87
  const configContent = {
86
88
  name: projectName,
87
89
  srcDir: 'src',
88
90
  platformVersion: '2023.2',
89
91
  };
90
- const success = writeProjectConfig(configPath, configContent);
91
- SpinniesManager.succeed('cloneApp', {
92
- text: i18n(`${i18nKey}.cloneStatus.done`),
92
+ const success = (0, projects_1.writeProjectConfig)(configPath, configContent);
93
+ SpinniesManager_1.default.succeed('cloneApp', {
94
+ text: (0, lang_1.i18n)(`${i18nKey}.cloneStatus.done`),
93
95
  succeedColor: 'white',
94
96
  });
95
97
  if (!success) {
96
- logger.error(i18n(`${i18nKey}.errors.couldNotWriteConfigPath`), configPath);
98
+ logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.couldNotWriteConfigPath`), configPath);
97
99
  }
98
- logger.log('');
99
- uiLine();
100
- logger.success(i18n(`${i18nKey}.cloneStatus.success`, { dest }));
101
- logger.log('');
102
- process.exit(EXIT_CODES.SUCCESS);
100
+ logger_1.logger.log('');
101
+ (0, ui_2.uiLine)();
102
+ logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.cloneStatus.success`, { dest: projectDest }));
103
+ logger_1.logger.log('');
104
+ process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
103
105
  }
104
106
  }
105
107
  catch (error) {
106
- await trackCommandMetadataUsage('clone-app', { status: 'FAILURE' }, derivedAccountId);
107
- SpinniesManager.fail('cloneApp', {
108
- text: i18n(`${i18nKey}.cloneStatus.failure`),
108
+ await (0, usageTracking_1.trackCommandMetadataUsage)('clone-app', { successful: false }, derivedAccountId);
109
+ SpinniesManager_1.default.fail('cloneApp', {
110
+ text: (0, lang_1.i18n)(`${i18nKey}.cloneStatus.failure`),
109
111
  failColor: 'white',
110
112
  });
111
113
  // Migrations endpoints return a response object with an errors property. The errors property contains an array of errors.
112
- if (error.errors && Array.isArray(error.errors)) {
113
- error.errors.forEach(e => logError(e, new ApiErrorContext({ accountId: derivedAccountId })));
114
+ if (error &&
115
+ typeof error === 'object' &&
116
+ 'errors' in error &&
117
+ Array.isArray(error.errors)) {
118
+ error.errors.forEach(e => (0, errorHandlers_1.logError)(e, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId })));
114
119
  }
115
120
  else {
116
- logError(error, new ApiErrorContext({ accountId: derivedAccountId }));
121
+ (0, errorHandlers_1.logError)(error, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId }));
117
122
  }
118
123
  }
119
- await trackCommandMetadataUsage('clone-app', { status: 'SUCCESS' }, derivedAccountId);
120
- process.exit(EXIT_CODES.SUCCESS);
124
+ await (0, usageTracking_1.trackCommandMetadataUsage)('clone-app', { successful: true }, derivedAccountId);
125
+ process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
121
126
  };
122
- exports.builder = yargs => {
127
+ exports.handler = handler;
128
+ const builder = (yargs) => {
123
129
  yargs.options({
124
130
  dest: {
125
- describe: i18n(`${i18nKey}.options.dest.describe`),
131
+ describe: (0, lang_1.i18n)(`${i18nKey}.options.dest.describe`),
126
132
  type: 'string',
127
133
  },
128
134
  'app-id': {
129
- describe: i18n(`${i18nKey}.options.appId.describe`),
135
+ describe: (0, lang_1.i18n)(`${i18nKey}.options.appId.describe`),
130
136
  type: 'number',
131
137
  },
132
138
  });
133
139
  yargs.example([
134
- ['$0 project clone-app', i18n(`${i18nKey}.examples.default`)],
140
+ ['$0 project clone-app', (0, lang_1.i18n)(`${i18nKey}.examples.default`)],
135
141
  ]);
136
- addConfigOptions(yargs);
137
- addAccountOptions(yargs);
138
- addUseEnvironmentOptions(yargs);
142
+ (0, commonOpts_1.addConfigOptions)(yargs);
143
+ (0, commonOpts_1.addAccountOptions)(yargs);
144
+ (0, commonOpts_1.addUseEnvironmentOptions)(yargs);
139
145
  return yargs;
140
146
  };
147
+ exports.builder = builder;
148
+ const cloneAppCommand = {
149
+ command: exports.command,
150
+ describe: exports.describe,
151
+ handler: exports.handler,
152
+ builder: exports.builder,
153
+ deprecated: exports.deprecated,
154
+ };
155
+ exports.default = cloneAppCommand;
@@ -87,7 +87,6 @@ exports.handler = async (options) => {
87
87
  'projectCommandTip',
88
88
  'projectUploadCommand',
89
89
  'projectDevCommand',
90
- 'projectInstallDepsCommand',
91
90
  'projectHelpCommand',
92
91
  'feedbackCommand',
93
92
  'sampleProjects',
@@ -1 +1,9 @@
1
- export {};
1
+ import { ArgumentsCamelCase, Argv, CommandModule } from 'yargs';
2
+ import { MigrateAppOptions } from '../../types/Yargs';
3
+ export declare const command = "migrate-app";
4
+ export declare const describe: string | undefined;
5
+ export declare const deprecated = true;
6
+ export declare function handler(yargs: ArgumentsCamelCase<MigrateAppOptions>): Promise<void>;
7
+ export declare function builder(yargs: Argv): Argv<MigrateAppOptions>;
8
+ declare const migrateAppCommand: CommandModule<unknown, MigrateAppOptions>;
9
+ export default migrateAppCommand;