@hubspot/cli 7.7.16-experimental.4 → 7.7.16-experimental.6

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.
@@ -2,7 +2,7 @@ import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModul
2
2
  type InstallAppArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs & {
3
3
  appUid?: string;
4
4
  projectName?: string;
5
- testAccountId?: number;
5
+ testAccountId: number;
6
6
  };
7
7
  declare const installAppCommand: YargsCommandModule<unknown, InstallAppArgs>;
8
8
  export default installAppCommand;
@@ -8,18 +8,53 @@ const usageTracking_1 = require("../../lib/usageTracking");
8
8
  const en_1 = require("../../lang/en");
9
9
  const exitCodes_1 = require("../../lib/enums/exitCodes");
10
10
  const yargsUtils_1 = require("../../lib/yargsUtils");
11
+ const constants_1 = require("../../lib/constants");
11
12
  const logger_1 = require("../../lib/ui/logger");
12
13
  const SpinniesManager_1 = __importDefault(require("../../lib/ui/SpinniesManager"));
13
14
  const errorHandlers_1 = require("../../lib/errorHandlers");
14
15
  const polling_1 = require("../../lib/polling");
15
- const command = 'install';
16
+ const config_1 = require("../../lib/projects/config");
17
+ const upload_1 = require("../../lib/projects/upload");
18
+ const structure_1 = require("../../lib/projects/structure");
19
+ const command = 'install <test-account-id>';
16
20
  const describe = undefined; // commands.app.subcommands.install.describe;
17
21
  async function handler(args) {
18
22
  const { derivedAccountId, appUid, projectName, testAccountId, formatOutputAsJson, } = args;
19
23
  (0, usageTracking_1.trackCommandUsage)('app-install', {}, derivedAccountId);
20
24
  const jsonOutput = {};
25
+ let targetProjectName = projectName;
26
+ let targetAppUid = appUid;
27
+ const { projectConfig, projectDir } = await (0, config_1.getProjectConfig)();
28
+ if (!targetProjectName) {
29
+ (0, config_1.validateProjectConfig)(projectConfig, projectDir);
30
+ targetProjectName = projectConfig?.name;
31
+ }
32
+ if (!targetProjectName) {
33
+ logger_1.uiLogger.error(en_1.commands.app.subcommands.install.errors.mustSpecifyProjectName);
34
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
35
+ }
36
+ let isAppOauth = true;
37
+ if (!targetAppUid) {
38
+ const intermediateRepresentation = await (0, upload_1.handleTranslate)(projectDir, projectConfig, derivedAccountId, true, undefined);
39
+ if (intermediateRepresentation) {
40
+ Object.values(intermediateRepresentation.intermediateNodesIndexedByUid).forEach(node => {
41
+ if ((0, structure_1.isAppIRNode)(node)) {
42
+ targetAppUid = node.uid;
43
+ isAppOauth = node.config.auth.type === constants_1.APP_AUTH_TYPES.OAUTH;
44
+ }
45
+ });
46
+ }
47
+ }
48
+ if (!targetAppUid) {
49
+ logger_1.uiLogger.error(en_1.commands.app.subcommands.install.errors.noAppUidFound);
50
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
51
+ }
52
+ if (!isAppOauth) {
53
+ logger_1.uiLogger.error(en_1.commands.app.subcommands.install.errors.appMustBeOauth);
54
+ process.exit(exitCodes_1.EXIT_CODES.ERROR);
55
+ }
21
56
  try {
22
- const { data } = await (0, developerTestAccounts_1.installOauthAppIntoDeveloperTestAccount)(derivedAccountId, testAccountId, projectName, appUid);
57
+ const { data } = await (0, developerTestAccounts_1.installOauthAppIntoDeveloperTestAccount)(derivedAccountId, testAccountId, targetProjectName, targetAppUid);
23
58
  if (data?.authCodes.length > 0) {
24
59
  jsonOutput.authCode = data.authCodes[0].authCode;
25
60
  }
@@ -36,7 +71,7 @@ async function handler(args) {
36
71
  });
37
72
  let appInstallSucceeded = false;
38
73
  try {
39
- await (0, polling_1.poll)(() => (0, developerTestAccounts_1.fetchDeveloperTestAccountOauthAppInstallStatus)(derivedAccountId, projectName, appUid), {
74
+ await (0, polling_1.poll)(() => (0, developerTestAccounts_1.fetchDeveloperTestAccountOauthAppInstallStatus)(derivedAccountId, targetProjectName, targetAppUid), {
40
75
  successStates: ['SUCCESS'],
41
76
  errorStates: [],
42
77
  });
@@ -60,11 +95,12 @@ async function handler(args) {
60
95
  process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
61
96
  }
62
97
  function installAppBuilder(yargs) {
63
- yargs.option('test-account-id', {
64
- describe: en_1.commands.app.subcommands.install.options.testAccountId,
98
+ yargs.positional('test-account-id', {
99
+ describe: en_1.commands.app.subcommands.install.positionals.testAccountId,
100
+ required: true,
65
101
  type: 'number',
66
102
  });
67
- yargs.positional('app-uid', {
103
+ yargs.option('app-uid', {
68
104
  describe: en_1.commands.app.subcommands.install.options.appUid,
69
105
  type: 'string',
70
106
  });
@@ -72,7 +108,7 @@ function installAppBuilder(yargs) {
72
108
  describe: en_1.commands.app.subcommands.install.options.projectName,
73
109
  type: 'string',
74
110
  });
75
- yargs.example('install --app-uid=1234567890 --project-name=my-project', en_1.commands.app.subcommands.install.example);
111
+ yargs.example('install 1234567890 --app-uid=my-app-uid --project-name=my-project', en_1.commands.app.subcommands.install.example);
76
112
  return yargs;
77
113
  }
78
114
  const builder = (0, yargsUtils_1.makeYargsBuilder)(installAppBuilder, command, en_1.commands.app.subcommands.install.describe, {
@@ -92,8 +92,10 @@ async function handler(args) {
92
92
  await (0, polling_1.poll)(() => (0, developerTestAccounts_1.fetchDeveloperTestAccountGateSyncStatus)(derivedAccountId, testAccountId), {
93
93
  successStates: ['SUCCESS'],
94
94
  errorStates: [],
95
- }, 5000 // 5 seconds
96
- );
95
+ });
96
+ // HACK: The status endpoint sometimes returns an early success status.
97
+ // Sleep for an extra 2 seconds to make sure the sync is actually complete.
98
+ await new Promise(resolve => setTimeout(resolve, 2000));
97
99
  SpinniesManager_1.default.succeed('createTestAccount', {
98
100
  text: en_1.commands.testAccount.create.polling.success(testAccountConfig.accountName, testAccountId),
99
101
  });
package/lang/en.d.ts CHANGED
@@ -1499,19 +1499,26 @@ ${string}`;
1499
1499
  readonly describe: "Commands for managing apps.";
1500
1500
  readonly subcommands: {
1501
1501
  readonly install: {
1502
- readonly describe: "Install an app.";
1502
+ readonly describe: "Install an OAuth app into a test account.";
1503
1503
  readonly options: {
1504
1504
  readonly appUid: "The uid of the app to install";
1505
- readonly projectName: "The name of the project to install the app to";
1505
+ readonly projectName: "The name of the project that contains the app";
1506
+ };
1507
+ readonly positionals: {
1506
1508
  readonly testAccountId: "The id of the test account to install the app into";
1507
1509
  };
1510
+ readonly errors: {
1511
+ readonly mustSpecifyProjectName: `You must specify a project name. Use the ${string} flag to specify the project name or run this command from within a project directory.`;
1512
+ readonly noAppUidFound: `No app uid found. Please specify the app uid with the ${string} flag or run this command from within a project that contains an app.`;
1513
+ readonly appMustBeOauth: "This command only supports installing oauth apps. Please specify an app with oauth auth type.";
1514
+ };
1508
1515
  readonly polling: {
1509
1516
  readonly start: "Installing app...";
1510
1517
  readonly success: "App installed successfully";
1511
1518
  readonly failure: "App installation failed";
1512
1519
  readonly error: "Error installing app";
1513
1520
  };
1514
- readonly example: "Install the app with uid 1234567890 from the project named \"my-project\" into the target account";
1521
+ readonly example: "Install the app with uid my-app-uid from the project named \"my-project\" into the target account with id 1234567890";
1515
1522
  };
1516
1523
  readonly secret: {
1517
1524
  readonly describe: "Commands for managing secrets.";
package/lang/en.js CHANGED
@@ -1497,19 +1497,26 @@ exports.commands = {
1497
1497
  describe: 'Commands for managing apps.',
1498
1498
  subcommands: {
1499
1499
  install: {
1500
- describe: 'Install an app.',
1500
+ describe: 'Install an OAuth app into a test account.',
1501
1501
  options: {
1502
1502
  appUid: 'The uid of the app to install',
1503
- projectName: 'The name of the project to install the app to',
1503
+ projectName: 'The name of the project that contains the app',
1504
+ },
1505
+ positionals: {
1504
1506
  testAccountId: 'The id of the test account to install the app into',
1505
1507
  },
1508
+ errors: {
1509
+ mustSpecifyProjectName: `You must specify a project name. Use the ${(0, ui_1.uiCommandReference)('--project-name')} flag to specify the project name or run this command from within a project directory.`,
1510
+ noAppUidFound: `No app uid found. Please specify the app uid with the ${(0, ui_1.uiCommandReference)('--app-uid')} flag or run this command from within a project that contains an app.`,
1511
+ appMustBeOauth: 'This command only supports installing oauth apps. Please specify an app with oauth auth type.',
1512
+ },
1506
1513
  polling: {
1507
1514
  start: 'Installing app...',
1508
1515
  success: 'App installed successfully',
1509
1516
  failure: 'App installation failed',
1510
1517
  error: 'Error installing app',
1511
1518
  },
1512
- example: 'Install the app with uid 1234567890 from the project named "my-project" into the target account',
1519
+ example: 'Install the app with uid my-app-uid from the project named "my-project" into the target account with id 1234567890',
1513
1520
  },
1514
1521
  secret: {
1515
1522
  describe: 'Commands for managing secrets.',
@@ -1,5 +1,5 @@
1
1
  import { ComponentTypes, Component, GenericComponentConfig, PublicAppComponentConfig, PrivateAppComponentConfig, AppCardComponentConfig } from '../../types/Projects';
2
- import { IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types';
2
+ import { IntermediateRepresentationNode, IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types';
3
3
  import { AppIRNode } from '../../types/ProjectComponents';
4
4
  export declare const CONFIG_FILES: {
5
5
  [k in ComponentTypes]: string;
@@ -15,4 +15,4 @@ export declare function getProjectComponentTypes(components: Array<Component>):
15
15
  export declare function getComponentUid(component?: Component | null): string | null;
16
16
  export declare function componentIsApp(component?: Component | null): component is Component<PublicAppComponentConfig | PrivateAppComponentConfig>;
17
17
  export declare function componentIsPublicApp(component?: Component | null): component is Component<PublicAppComponentConfig>;
18
- export declare function isAppIRNode(component: IntermediateRepresentationNodeLocalDev): component is AppIRNode;
18
+ export declare function isAppIRNode(component: IntermediateRepresentationNodeLocalDev | IntermediateRepresentationNode): component is AppIRNode;
@@ -1,4 +1,5 @@
1
1
  import { FileResult } from 'tmp';
2
+ import { IntermediateRepresentation } from '@hubspot/project-parsing-lib';
2
3
  import { ProjectConfig } from '../../types/Projects';
3
4
  type ProjectUploadCallbackFunction<T> = (accountId: number, projectConfig: ProjectConfig, tempFile: FileResult, buildId: number) => Promise<T>;
4
5
  type ProjectUploadResult<T> = {
@@ -20,5 +21,5 @@ type HandleProjectUploadArg<T> = {
20
21
  export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
21
22
  export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig): void;
22
23
  export declare function validateNoHSMetaMismatch(srcDir: string, projectConfig: ProjectConfig): Promise<void>;
23
- export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<unknown>;
24
+ export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<IntermediateRepresentation | undefined>;
24
25
  export {};
@@ -149,4 +149,5 @@ async function handleTranslate(projectDir, projectConfig, accountId, skipValidat
149
149
  (0, errorHandlers_1.logError)(e);
150
150
  }
151
151
  }
152
+ return undefined;
152
153
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "7.7.16-experimental.4",
3
+ "version": "7.7.16-experimental.6",
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
  "dependencies": {
8
- "@hubspot/local-dev-lib": "3.11.0",
8
+ "@hubspot/local-dev-lib": "3.12.0",
9
9
  "@hubspot/project-parsing-lib": "0.5.0",
10
10
  "@hubspot/serverless-dev-runtime": "7.0.6",
11
11
  "@hubspot/theme-preview-dev-server": "0.0.10",