@hubspot/cli 7.7.16-experimental.3 → 7.7.16-experimental.5
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/commands/app/install.d.ts +8 -0
- package/commands/app/install.js +127 -0
- package/commands/app.js +6 -1
- package/commands/getStarted.js +2 -2
- package/commands/project/cloneApp.js +4 -4
- package/commands/project/create.js +9 -9
- package/commands/project/dev/unifiedFlow.js +1 -0
- package/commands/testAccount/create.js +11 -4
- package/lang/en.d.ts +36 -3
- package/lang/en.js +36 -3
- package/lib/app/migrate_legacy.js +2 -3
- package/lib/polling.d.ts +1 -1
- package/lib/polling.js +11 -1
- package/lib/projects/add/v3AddComponent.js +4 -0
- package/lib/projects/create/index.d.ts +3 -2
- package/lib/projects/create/index.js +11 -5
- package/lib/projects/create/v3.d.ts +3 -3
- package/lib/projects/create/v3.js +2 -2
- package/lib/projects/localDev/LocalDevProcess.d.ts +3 -2
- package/lib/projects/localDev/LocalDevProcess.js +16 -12
- package/lib/projects/localDev/LocalDevState.d.ts +10 -5
- package/lib/projects/localDev/LocalDevState.js +18 -20
- package/lib/projects/localDev/LocalDevWatcher.js +1 -1
- package/lib/projects/structure.d.ts +2 -2
- package/lib/projects/upload.d.ts +2 -1
- package/lib/projects/upload.js +1 -0
- package/lib/prompts/projectNameAndDestPrompt.d.ts +3 -0
- package/lib/prompts/projectNameAndDestPrompt.js +60 -0
- package/lib/prompts/selectProjectTemplatePrompt.d.ts +26 -0
- package/lib/prompts/{createProjectPrompt.js → selectProjectTemplatePrompt.js} +6 -55
- package/package.json +2 -2
- package/types/LocalDev.d.ts +1 -0
- package/lib/prompts/createProjectPrompt.d.ts +0 -28
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModule, JSONOutputArgs } from '../../types/Yargs';
|
|
2
|
+
type InstallAppArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs & {
|
|
3
|
+
appUid?: string;
|
|
4
|
+
projectName?: string;
|
|
5
|
+
testAccountId: number;
|
|
6
|
+
};
|
|
7
|
+
declare const installAppCommand: YargsCommandModule<unknown, InstallAppArgs>;
|
|
8
|
+
export default installAppCommand;
|
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
const developerTestAccounts_1 = require("@hubspot/local-dev-lib/api/developerTestAccounts");
|
|
7
|
+
const usageTracking_1 = require("../../lib/usageTracking");
|
|
8
|
+
const en_1 = require("../../lang/en");
|
|
9
|
+
const exitCodes_1 = require("../../lib/enums/exitCodes");
|
|
10
|
+
const yargsUtils_1 = require("../../lib/yargsUtils");
|
|
11
|
+
const constants_1 = require("../../lib/constants");
|
|
12
|
+
const logger_1 = require("../../lib/ui/logger");
|
|
13
|
+
const SpinniesManager_1 = __importDefault(require("../../lib/ui/SpinniesManager"));
|
|
14
|
+
const errorHandlers_1 = require("../../lib/errorHandlers");
|
|
15
|
+
const polling_1 = require("../../lib/polling");
|
|
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>';
|
|
20
|
+
const describe = undefined; // commands.app.subcommands.install.describe;
|
|
21
|
+
async function handler(args) {
|
|
22
|
+
const { derivedAccountId, appUid, projectName, testAccountId, formatOutputAsJson, } = args;
|
|
23
|
+
(0, usageTracking_1.trackCommandUsage)('app-install', {}, derivedAccountId);
|
|
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
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const { data } = await (0, developerTestAccounts_1.installOauthAppIntoDeveloperTestAccount)(derivedAccountId, testAccountId, targetProjectName, targetAppUid);
|
|
58
|
+
if (data?.authCodes.length > 0) {
|
|
59
|
+
jsonOutput.authCode = data.authCodes[0].authCode;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
(0, errorHandlers_1.logError)(err);
|
|
64
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
65
|
+
}
|
|
66
|
+
SpinniesManager_1.default.init({
|
|
67
|
+
succeedColor: 'white',
|
|
68
|
+
});
|
|
69
|
+
SpinniesManager_1.default.add('installApp', {
|
|
70
|
+
text: en_1.commands.app.subcommands.install.polling.start,
|
|
71
|
+
});
|
|
72
|
+
let appInstallSucceeded = false;
|
|
73
|
+
try {
|
|
74
|
+
await (0, polling_1.poll)(() => (0, developerTestAccounts_1.fetchDeveloperTestAccountOauthAppInstallStatus)(derivedAccountId, targetProjectName, targetAppUid), {
|
|
75
|
+
successStates: ['SUCCESS'],
|
|
76
|
+
errorStates: [],
|
|
77
|
+
});
|
|
78
|
+
appInstallSucceeded = true;
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
SpinniesManager_1.default.fail('installApp');
|
|
82
|
+
(0, errorHandlers_1.logError)(err);
|
|
83
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
84
|
+
}
|
|
85
|
+
if (!appInstallSucceeded) {
|
|
86
|
+
SpinniesManager_1.default.fail('installApp');
|
|
87
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
88
|
+
}
|
|
89
|
+
SpinniesManager_1.default.succeed('installApp', {
|
|
90
|
+
text: en_1.commands.app.subcommands.install.polling.success,
|
|
91
|
+
});
|
|
92
|
+
if (formatOutputAsJson) {
|
|
93
|
+
logger_1.uiLogger.json(jsonOutput);
|
|
94
|
+
}
|
|
95
|
+
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
96
|
+
}
|
|
97
|
+
function installAppBuilder(yargs) {
|
|
98
|
+
yargs.positional('test-account-id', {
|
|
99
|
+
describe: en_1.commands.app.subcommands.install.positionals.testAccountId,
|
|
100
|
+
required: true,
|
|
101
|
+
type: 'number',
|
|
102
|
+
});
|
|
103
|
+
yargs.option('app-uid', {
|
|
104
|
+
describe: en_1.commands.app.subcommands.install.options.appUid,
|
|
105
|
+
type: 'string',
|
|
106
|
+
});
|
|
107
|
+
yargs.option('project-name', {
|
|
108
|
+
describe: en_1.commands.app.subcommands.install.options.projectName,
|
|
109
|
+
type: 'string',
|
|
110
|
+
});
|
|
111
|
+
yargs.example('install 1234567890 --app-uid=my-app-uid --project-name=my-project', en_1.commands.app.subcommands.install.example);
|
|
112
|
+
return yargs;
|
|
113
|
+
}
|
|
114
|
+
const builder = (0, yargsUtils_1.makeYargsBuilder)(installAppBuilder, command, en_1.commands.app.subcommands.install.describe, {
|
|
115
|
+
useGlobalOptions: true,
|
|
116
|
+
useAccountOptions: true,
|
|
117
|
+
useConfigOptions: true,
|
|
118
|
+
useEnvironmentOptions: true,
|
|
119
|
+
useJSONOutputOptions: true,
|
|
120
|
+
});
|
|
121
|
+
const installAppCommand = {
|
|
122
|
+
command,
|
|
123
|
+
describe,
|
|
124
|
+
handler,
|
|
125
|
+
builder,
|
|
126
|
+
};
|
|
127
|
+
exports.default = installAppCommand;
|
package/commands/app.js
CHANGED
|
@@ -5,12 +5,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const migrate_1 = __importDefault(require("./app/migrate"));
|
|
7
7
|
const secret_1 = __importDefault(require("./app/secret"));
|
|
8
|
+
const install_1 = __importDefault(require("./app/install"));
|
|
8
9
|
const yargsUtils_1 = require("../lib/yargsUtils");
|
|
9
10
|
const command = ['app', 'apps'];
|
|
10
11
|
// Keep the command hidden for now
|
|
11
12
|
const describe = undefined;
|
|
12
13
|
function appBuilder(yargs) {
|
|
13
|
-
yargs
|
|
14
|
+
yargs
|
|
15
|
+
.command(migrate_1.default)
|
|
16
|
+
.command(secret_1.default)
|
|
17
|
+
.command(install_1.default)
|
|
18
|
+
.demandCommand(1, '');
|
|
14
19
|
return yargs;
|
|
15
20
|
}
|
|
16
21
|
const builder = (0, yargsUtils_1.makeYargsBuilder)(appBuilder, command, describe);
|
package/commands/getStarted.js
CHANGED
|
@@ -14,7 +14,7 @@ const usageTracking_1 = require("../lib/usageTracking");
|
|
|
14
14
|
const exitCodes_1 = require("../lib/enums/exitCodes");
|
|
15
15
|
const yargsUtils_1 = require("../lib/yargsUtils");
|
|
16
16
|
const promptUtils_1 = require("../lib/prompts/promptUtils");
|
|
17
|
-
const
|
|
17
|
+
const projectNameAndDestPrompt_1 = require("../lib/prompts/projectNameAndDestPrompt");
|
|
18
18
|
const ui_1 = require("../lib/ui");
|
|
19
19
|
const logger_1 = require("../lib/ui/logger");
|
|
20
20
|
const errorHandlers_1 = require("../lib/errorHandlers");
|
|
@@ -76,7 +76,7 @@ async function handler(args) {
|
|
|
76
76
|
logger_1.uiLogger.log(en_1.commands.getStarted.prompts.appSelected);
|
|
77
77
|
// 1. Fetch project templates
|
|
78
78
|
let latestRepoReleaseTag;
|
|
79
|
-
const { dest, name } = await (0,
|
|
79
|
+
const { dest, name } = await (0, projectNameAndDestPrompt_1.projectNameAndDestPrompt)(args);
|
|
80
80
|
// Specific template for get-started command
|
|
81
81
|
const projectTemplate = {
|
|
82
82
|
name: 'private-app-get-started-template',
|
|
@@ -8,7 +8,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
8
8
|
const usageTracking_1 = require("../../lib/usageTracking");
|
|
9
9
|
const lang_1 = require("../../lib/lang");
|
|
10
10
|
const selectPublicAppForMigrationPrompt_1 = require("../../lib/prompts/selectPublicAppForMigrationPrompt");
|
|
11
|
-
const
|
|
11
|
+
const projectNameAndDestPrompt_1 = require("../../lib/prompts/projectNameAndDestPrompt");
|
|
12
12
|
const polling_1 = require("../../lib/polling");
|
|
13
13
|
const errorHandlers_1 = require("../../lib/errorHandlers");
|
|
14
14
|
const exitCodes_1 = require("../../lib/enums/exitCodes");
|
|
@@ -53,9 +53,9 @@ async function handler(args) {
|
|
|
53
53
|
});
|
|
54
54
|
appId = appIdResponse.appId;
|
|
55
55
|
}
|
|
56
|
-
const
|
|
57
|
-
projectName =
|
|
58
|
-
projectDest =
|
|
56
|
+
const projectNameAndDestPromptResponse = await (0, projectNameAndDestPrompt_1.projectNameAndDestPrompt)(args);
|
|
57
|
+
projectName = projectNameAndDestPromptResponse.name;
|
|
58
|
+
projectDest = projectNameAndDestPromptResponse.dest;
|
|
59
59
|
}
|
|
60
60
|
catch (error) {
|
|
61
61
|
(0, errorHandlers_1.logError)(error, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId }));
|
|
@@ -39,15 +39,15 @@ async function handler(args) {
|
|
|
39
39
|
(0, errorHandlers_1.logError)(error);
|
|
40
40
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
41
41
|
}
|
|
42
|
-
const { authType, distribution, repoConfig, projectContents,
|
|
42
|
+
const { authType, distribution, repoConfig, projectContents, selectProjectTemplatePromptResponse, projectNameAndDestPromptResponse, } = handleResult;
|
|
43
43
|
(0, usageTracking_1.trackCommandUsage)('project-create', {
|
|
44
|
-
type:
|
|
45
|
-
(
|
|
44
|
+
type: selectProjectTemplatePromptResponse.projectTemplate?.name ||
|
|
45
|
+
(selectProjectTemplatePromptResponse.componentTemplates || [])
|
|
46
46
|
// @ts-expect-error
|
|
47
47
|
.map((item) => item.label)
|
|
48
48
|
.join(','),
|
|
49
49
|
}, derivedAccountId);
|
|
50
|
-
const projectDest = path_1.default.resolve((0, path_2.getCwd)(),
|
|
50
|
+
const projectDest = path_1.default.resolve((0, path_2.getCwd)(), projectNameAndDestPromptResponse.dest);
|
|
51
51
|
const { projectConfig: existingProjectConfig, projectDir: existingProjectDir, } = await (0, config_1.getProjectConfig)(projectDest);
|
|
52
52
|
// Exit if the target destination is within an existing project
|
|
53
53
|
if (existingProjectConfig &&
|
|
@@ -57,7 +57,7 @@ async function handler(args) {
|
|
|
57
57
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
58
58
|
}
|
|
59
59
|
const components = (0, v3_2.generateComponentPaths)({
|
|
60
|
-
|
|
60
|
+
selectProjectTemplatePromptResponse,
|
|
61
61
|
platformVersion,
|
|
62
62
|
repoConfig,
|
|
63
63
|
projectContents,
|
|
@@ -66,7 +66,7 @@ async function handler(args) {
|
|
|
66
66
|
});
|
|
67
67
|
try {
|
|
68
68
|
await (0, github_1.cloneGithubRepo)(repo, projectDest, {
|
|
69
|
-
sourceDir:
|
|
69
|
+
sourceDir: selectProjectTemplatePromptResponse.projectTemplate?.path || components,
|
|
70
70
|
hideLogs: true,
|
|
71
71
|
branch: 'main',
|
|
72
72
|
});
|
|
@@ -80,15 +80,15 @@ async function handler(args) {
|
|
|
80
80
|
const parsedConfigFile = JSON.parse(fs_extra_1.default.readFileSync(projectConfigPath).toString());
|
|
81
81
|
(0, config_1.writeProjectConfig)(projectConfigPath, {
|
|
82
82
|
...parsedConfigFile,
|
|
83
|
-
name:
|
|
83
|
+
name: projectNameAndDestPromptResponse.name,
|
|
84
84
|
});
|
|
85
85
|
// If the template is 'no-template', we need to manually create a src directory
|
|
86
|
-
if (
|
|
86
|
+
if (selectProjectTemplatePromptResponse.projectTemplate?.name ===
|
|
87
87
|
legacy_1.EMPTY_PROJECT_TEMPLATE_NAME ||
|
|
88
88
|
projectContents === v3_1.EMPTY_PROJECT) {
|
|
89
89
|
fs_extra_1.default.ensureDirSync(path_1.default.join(projectDest, 'src'));
|
|
90
90
|
}
|
|
91
|
-
logger_1.uiLogger.success(en_1.commands.project.create.logs.success(
|
|
91
|
+
logger_1.uiLogger.success(en_1.commands.project.create.logs.success(projectNameAndDestPromptResponse.name, projectDest));
|
|
92
92
|
logger_1.uiLogger.log(en_1.commands.project.create.logs.welcomeMessage);
|
|
93
93
|
(0, ui_1.uiFeatureHighlight)([
|
|
94
94
|
'projectCommandTip',
|
|
@@ -121,6 +121,7 @@ async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTar
|
|
|
121
121
|
debug: args.debug,
|
|
122
122
|
deployedBuild,
|
|
123
123
|
isGithubLinked,
|
|
124
|
+
profile: args.profile,
|
|
124
125
|
targetProjectAccountId,
|
|
125
126
|
targetTestingAccountId: targetTestingAccountId,
|
|
126
127
|
projectConfig,
|
|
@@ -92,14 +92,21 @@ 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
|
+
);
|
|
97
|
+
// HACK: The status endpoint sometimes returns an early success status.
|
|
98
|
+
// Sleep for an extra 5 seconds to make sure the status is actually success.
|
|
99
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
100
|
+
SpinniesManager_1.default.succeed('createTestAccount', {
|
|
101
|
+
text: en_1.commands.testAccount.create.polling.success(testAccountConfig.accountName, testAccountId),
|
|
95
102
|
});
|
|
96
103
|
}
|
|
97
104
|
catch (err) {
|
|
98
|
-
(0, errorHandlers_1.
|
|
105
|
+
(0, errorHandlers_1.debugError)(err);
|
|
106
|
+
SpinniesManager_1.default.fail('createTestAccount', {
|
|
107
|
+
text: en_1.commands.testAccount.create.polling.failure,
|
|
108
|
+
});
|
|
99
109
|
}
|
|
100
|
-
SpinniesManager_1.default.succeed('createTestAccount', {
|
|
101
|
-
text: en_1.commands.testAccount.create.polling.success(testAccountConfig.accountName, testAccountId),
|
|
102
|
-
});
|
|
103
110
|
if (formatOutputAsJson) {
|
|
104
111
|
logger_1.uiLogger.json(jsonOutput);
|
|
105
112
|
}
|
package/lang/en.d.ts
CHANGED
|
@@ -1498,6 +1498,28 @@ ${string}`;
|
|
|
1498
1498
|
readonly app: {
|
|
1499
1499
|
readonly describe: "Commands for managing apps.";
|
|
1500
1500
|
readonly subcommands: {
|
|
1501
|
+
readonly install: {
|
|
1502
|
+
readonly describe: "Install an app.";
|
|
1503
|
+
readonly options: {
|
|
1504
|
+
readonly appUid: "The uid of the app to install";
|
|
1505
|
+
readonly projectName: "The name of the project to install the app to";
|
|
1506
|
+
};
|
|
1507
|
+
readonly positionals: {
|
|
1508
|
+
readonly testAccountId: "The id of the test account to install the app into";
|
|
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
|
+
};
|
|
1515
|
+
readonly polling: {
|
|
1516
|
+
readonly start: "Installing app...";
|
|
1517
|
+
readonly success: "App installed successfully";
|
|
1518
|
+
readonly failure: "App installation failed";
|
|
1519
|
+
readonly error: "Error installing app";
|
|
1520
|
+
};
|
|
1521
|
+
readonly example: "Install the app with uid my-app-uid from the project named \"my-project\" into the target account with id 1234567890";
|
|
1522
|
+
};
|
|
1501
1523
|
readonly secret: {
|
|
1502
1524
|
readonly describe: "Commands for managing secrets.";
|
|
1503
1525
|
readonly subcommands: {
|
|
@@ -1807,6 +1829,7 @@ ${string}`;
|
|
|
1807
1829
|
readonly start: (testAccountName: string) => string;
|
|
1808
1830
|
readonly syncing: "Test account created! Syncing account data... (may take a few minutes - you can exit and the sync will continue)";
|
|
1809
1831
|
readonly success: (testAccountName: string, testAccountId: number) => string;
|
|
1832
|
+
readonly failure: "Failed to sync data into test account. The account may not be ready to use.";
|
|
1810
1833
|
};
|
|
1811
1834
|
readonly options: {
|
|
1812
1835
|
readonly configPath: "The path to the test account config";
|
|
@@ -2608,6 +2631,9 @@ Run ${string} to upgrade to version ${string}`;
|
|
|
2608
2631
|
readonly invalidAuthDistCombo: (authType: string, distribution: string) => string;
|
|
2609
2632
|
};
|
|
2610
2633
|
};
|
|
2634
|
+
readonly add: {
|
|
2635
|
+
readonly nothingAdded: "No features added.";
|
|
2636
|
+
};
|
|
2611
2637
|
readonly validateProjectConfig: {
|
|
2612
2638
|
readonly configNotFound: `Unable to locate a project configuration file. Try running again from a project directory, or run ${string} to create a new project.`;
|
|
2613
2639
|
readonly configMissingFields: "The project configuration file is missing required fields.";
|
|
@@ -2918,16 +2944,20 @@ Run ${string} to upgrade to version ${string}`;
|
|
|
2918
2944
|
readonly languageRequired: "Please select API sample app's language";
|
|
2919
2945
|
};
|
|
2920
2946
|
};
|
|
2921
|
-
readonly
|
|
2947
|
+
readonly projectNameAndDestPrompt: {
|
|
2922
2948
|
readonly enterName: "[--name] Give your project a name: ";
|
|
2923
2949
|
readonly enterDest: "[--dest] Enter the folder to create the project in:";
|
|
2924
|
-
readonly selectTemplate: "[--template] Choose a project template: ";
|
|
2925
|
-
readonly features: "[--features] Which features would you like your app to include?";
|
|
2926
2950
|
readonly errors: {
|
|
2927
2951
|
readonly nameRequired: "A project name is required";
|
|
2928
2952
|
readonly destRequired: "A project dest is required";
|
|
2929
2953
|
readonly invalidDest: "There is an existing project at this destination. Please provide a new path for this project.";
|
|
2930
2954
|
readonly invalidCharacters: "The selected destination contains invalid characters. Please provide a new path and try again.";
|
|
2955
|
+
};
|
|
2956
|
+
};
|
|
2957
|
+
readonly selectProjectTemplatePrompt: {
|
|
2958
|
+
readonly selectTemplate: "[--template] Choose a project template: ";
|
|
2959
|
+
readonly features: "[--features] Which features would you like your app to include?";
|
|
2960
|
+
readonly errors: {
|
|
2931
2961
|
readonly invalidTemplate: (template: string) => string;
|
|
2932
2962
|
readonly projectTemplateRequired: "Project template is required when projectTemplates is provided";
|
|
2933
2963
|
};
|
|
@@ -3032,6 +3062,9 @@ Run ${string} to upgrade to version ${string}`;
|
|
|
3032
3062
|
};
|
|
3033
3063
|
};
|
|
3034
3064
|
};
|
|
3065
|
+
readonly polling: {
|
|
3066
|
+
readonly timeoutError: (timeoutMs: number) => string;
|
|
3067
|
+
};
|
|
3035
3068
|
readonly convertFields: {
|
|
3036
3069
|
readonly positionals: {
|
|
3037
3070
|
readonly src: {
|
package/lang/en.js
CHANGED
|
@@ -1496,6 +1496,28 @@ exports.commands = {
|
|
|
1496
1496
|
app: {
|
|
1497
1497
|
describe: 'Commands for managing apps.',
|
|
1498
1498
|
subcommands: {
|
|
1499
|
+
install: {
|
|
1500
|
+
describe: 'Install an app.',
|
|
1501
|
+
options: {
|
|
1502
|
+
appUid: 'The uid of the app to install',
|
|
1503
|
+
projectName: 'The name of the project to install the app to',
|
|
1504
|
+
},
|
|
1505
|
+
positionals: {
|
|
1506
|
+
testAccountId: 'The id of the test account to install the app into',
|
|
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
|
+
},
|
|
1513
|
+
polling: {
|
|
1514
|
+
start: 'Installing app...',
|
|
1515
|
+
success: 'App installed successfully',
|
|
1516
|
+
failure: 'App installation failed',
|
|
1517
|
+
error: 'Error installing app',
|
|
1518
|
+
},
|
|
1519
|
+
example: 'Install the app with uid my-app-uid from the project named "my-project" into the target account with id 1234567890',
|
|
1520
|
+
},
|
|
1499
1521
|
secret: {
|
|
1500
1522
|
describe: 'Commands for managing secrets.',
|
|
1501
1523
|
subcommands: {
|
|
@@ -1805,6 +1827,7 @@ exports.commands = {
|
|
|
1805
1827
|
start: (testAccountName) => `Creating test account "${chalk_1.default.bold(testAccountName)}"...`,
|
|
1806
1828
|
syncing: 'Test account created! Syncing account data... (may take a few minutes - you can exit and the sync will continue)',
|
|
1807
1829
|
success: (testAccountName, testAccountId) => `Test account "${chalk_1.default.bold(testAccountName)}" successfully created with id: ${chalk_1.default.bold(testAccountId)}`,
|
|
1830
|
+
failure: 'Failed to sync data into test account. The account may not be ready to use.',
|
|
1808
1831
|
},
|
|
1809
1832
|
options: {
|
|
1810
1833
|
configPath: 'The path to the test account config',
|
|
@@ -2605,6 +2628,9 @@ exports.lib = {
|
|
|
2605
2628
|
invalidAuthDistCombo: (authType, distribution) => `Invalid distribution and auth combination. Apps with distribution '${distribution}' must have auth '${authType}'`,
|
|
2606
2629
|
},
|
|
2607
2630
|
},
|
|
2631
|
+
add: {
|
|
2632
|
+
nothingAdded: 'No features added.',
|
|
2633
|
+
},
|
|
2608
2634
|
validateProjectConfig: {
|
|
2609
2635
|
configNotFound: `Unable to locate a project configuration file. Try running again from a project directory, or run ${(0, ui_1.uiCommandReference)('hs project create')} to create a new project.`,
|
|
2610
2636
|
configMissingFields: 'The project configuration file is missing required fields.',
|
|
@@ -2913,16 +2939,20 @@ exports.lib = {
|
|
|
2913
2939
|
languageRequired: "Please select API sample app's language",
|
|
2914
2940
|
},
|
|
2915
2941
|
},
|
|
2916
|
-
|
|
2942
|
+
projectNameAndDestPrompt: {
|
|
2917
2943
|
enterName: '[--name] Give your project a name: ',
|
|
2918
2944
|
enterDest: '[--dest] Enter the folder to create the project in:',
|
|
2919
|
-
selectTemplate: '[--template] Choose a project template: ',
|
|
2920
|
-
features: '[--features] Which features would you like your app to include?',
|
|
2921
2945
|
errors: {
|
|
2922
2946
|
nameRequired: 'A project name is required',
|
|
2923
2947
|
destRequired: 'A project dest is required',
|
|
2924
2948
|
invalidDest: 'There is an existing project at this destination. Please provide a new path for this project.',
|
|
2925
2949
|
invalidCharacters: 'The selected destination contains invalid characters. Please provide a new path and try again.',
|
|
2950
|
+
},
|
|
2951
|
+
},
|
|
2952
|
+
selectProjectTemplatePrompt: {
|
|
2953
|
+
selectTemplate: '[--template] Choose a project template: ',
|
|
2954
|
+
features: '[--features] Which features would you like your app to include?',
|
|
2955
|
+
errors: {
|
|
2926
2956
|
invalidTemplate: (template) => `[--template] Could not find template "${template}". Please choose an available template:`,
|
|
2927
2957
|
projectTemplateRequired: 'Project template is required when projectTemplates is provided',
|
|
2928
2958
|
},
|
|
@@ -3027,6 +3057,9 @@ exports.lib = {
|
|
|
3027
3057
|
},
|
|
3028
3058
|
},
|
|
3029
3059
|
},
|
|
3060
|
+
polling: {
|
|
3061
|
+
timeoutError: (timeoutMs) => `Polling timed out after ${timeoutMs}ms.`,
|
|
3062
|
+
},
|
|
3030
3063
|
convertFields: {
|
|
3031
3064
|
positionals: {
|
|
3032
3065
|
src: {
|
|
@@ -18,7 +18,7 @@ const ui_1 = require("../ui");
|
|
|
18
18
|
const lang_1 = require("../lang");
|
|
19
19
|
const accountTypes_1 = require("../accountTypes");
|
|
20
20
|
const selectPublicAppForMigrationPrompt_1 = require("../prompts/selectPublicAppForMigrationPrompt");
|
|
21
|
-
const
|
|
21
|
+
const projectNameAndDestPrompt_1 = require("../prompts/projectNameAndDestPrompt");
|
|
22
22
|
const ensureProjectExists_1 = require("../projects/ensureProjectExists");
|
|
23
23
|
const usageTracking_1 = require("../usageTracking");
|
|
24
24
|
const SpinniesManager_1 = __importDefault(require("../ui/SpinniesManager"));
|
|
@@ -58,8 +58,7 @@ async function migrateApp2023_2(derivedAccountId, options, accountConfig) {
|
|
|
58
58
|
(0, errorHandlers_1.logError)(error, new errorHandlers_1.ApiErrorContext({ accountId: derivedAccountId }));
|
|
59
59
|
return process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
60
60
|
}
|
|
61
|
-
const
|
|
62
|
-
const { name: projectName, dest: projectDest } = createProjectPromptResponse;
|
|
61
|
+
const { name: projectName, dest: projectDest } = await (0, projectNameAndDestPrompt_1.projectNameAndDestPrompt)(options);
|
|
63
62
|
const { projectExists } = await (0, ensureProjectExists_1.ensureProjectExists)(derivedAccountId, projectName, {
|
|
64
63
|
allowCreate: false,
|
|
65
64
|
noLogs: true,
|
package/lib/polling.d.ts
CHANGED
|
@@ -17,5 +17,5 @@ type PollingCallback<T extends GenericPollingResponse> = () => HubSpotPromise<T>
|
|
|
17
17
|
export declare function poll<T extends GenericPollingResponse>(callback: PollingCallback<T>, statusLookup?: {
|
|
18
18
|
successStates: string[];
|
|
19
19
|
errorStates: string[];
|
|
20
|
-
}): Promise<T>;
|
|
20
|
+
}, timeoutMs?: number): Promise<T>;
|
|
21
21
|
export {};
|
package/lib/polling.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DEFAULT_POLLING_STATUS_LOOKUP = exports.DEFAULT_POLLING_STATES = void 0;
|
|
4
4
|
exports.poll = poll;
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
|
+
const en_1 = require("../lang/en");
|
|
6
7
|
exports.DEFAULT_POLLING_STATES = {
|
|
7
8
|
STARTED: 'STARTED',
|
|
8
9
|
SUCCESS: 'SUCCESS',
|
|
@@ -18,7 +19,8 @@ exports.DEFAULT_POLLING_STATUS_LOOKUP = {
|
|
|
18
19
|
exports.DEFAULT_POLLING_STATES.FAILURE,
|
|
19
20
|
],
|
|
20
21
|
};
|
|
21
|
-
function poll(callback, statusLookup = exports.DEFAULT_POLLING_STATUS_LOOKUP
|
|
22
|
+
function poll(callback, statusLookup = exports.DEFAULT_POLLING_STATUS_LOOKUP, timeoutMs = 60000 // Default 60 second timeout
|
|
23
|
+
) {
|
|
22
24
|
return new Promise((resolve, reject) => {
|
|
23
25
|
const pollInterval = setInterval(async () => {
|
|
24
26
|
try {
|
|
@@ -26,17 +28,25 @@ function poll(callback, statusLookup = exports.DEFAULT_POLLING_STATUS_LOOKUP) {
|
|
|
26
28
|
const { status } = pollResp;
|
|
27
29
|
if (statusLookup.successStates.includes(status)) {
|
|
28
30
|
clearInterval(pollInterval);
|
|
31
|
+
clearTimeout(timeoutId);
|
|
29
32
|
resolve(pollResp);
|
|
30
33
|
}
|
|
31
34
|
else if (statusLookup.errorStates.includes(status)) {
|
|
32
35
|
clearInterval(pollInterval);
|
|
36
|
+
clearTimeout(timeoutId);
|
|
33
37
|
reject(pollResp);
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
catch (error) {
|
|
37
41
|
clearInterval(pollInterval);
|
|
42
|
+
clearTimeout(timeoutId);
|
|
38
43
|
reject(error);
|
|
39
44
|
}
|
|
40
45
|
}, constants_1.DEFAULT_POLLING_DELAY);
|
|
46
|
+
// Set a timeout to stop polling after specified duration
|
|
47
|
+
const timeoutId = setTimeout(() => {
|
|
48
|
+
clearInterval(pollInterval);
|
|
49
|
+
reject(new Error(en_1.lib.polling.timeoutError(timeoutMs)));
|
|
50
|
+
}, timeoutMs);
|
|
41
51
|
});
|
|
42
52
|
}
|
|
@@ -66,6 +66,10 @@ async function v3AddComponent(args, projectDir, projectConfig) {
|
|
|
66
66
|
components.push(path_1.default.join(projectConfig.platformVersion, parentComponent.path));
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
if (components.length === 0) {
|
|
70
|
+
logger_1.uiLogger.log(en_1.lib.projects.add.nothingAdded);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
69
73
|
await (0, github_1.cloneGithubRepo)(constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, projectDir, {
|
|
70
74
|
sourceDir: components,
|
|
71
75
|
hideLogs: true,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ArgumentsCamelCase } from 'yargs';
|
|
2
2
|
import { ProjectTemplateRepoConfig } from '../../../types/Projects';
|
|
3
|
-
import {
|
|
3
|
+
import { SelectProjectTemplatePromptResponse, ProjectNameAndDestPromptResponse } from '../../prompts/selectProjectTemplatePrompt';
|
|
4
4
|
import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs } from '../../../types/Yargs';
|
|
5
5
|
import { RepoPath } from '@hubspot/local-dev-lib/types/Github';
|
|
6
6
|
export type ProjectCreateArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & {
|
|
@@ -19,5 +19,6 @@ export declare function handleProjectCreationFlow(args: ArgumentsCamelCase<Proje
|
|
|
19
19
|
distribution?: string;
|
|
20
20
|
repoConfig?: ProjectTemplateRepoConfig;
|
|
21
21
|
projectContents?: string;
|
|
22
|
-
|
|
22
|
+
selectProjectTemplatePromptResponse: SelectProjectTemplatePromptResponse;
|
|
23
|
+
projectNameAndDestPromptResponse: ProjectNameAndDestPromptResponse;
|
|
23
24
|
}>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleProjectCreationFlow = handleProjectCreationFlow;
|
|
4
|
-
const
|
|
4
|
+
const selectProjectTemplatePrompt_1 = require("../../prompts/selectProjectTemplatePrompt");
|
|
5
|
+
const projectNameAndDestPrompt_1 = require("../../prompts/projectNameAndDestPrompt");
|
|
5
6
|
const constants_1 = require("../../constants");
|
|
6
7
|
const buildAndDeploy_1 = require("../buildAndDeploy");
|
|
7
8
|
const v3_1 = require("./v3");
|
|
@@ -12,15 +13,17 @@ const exitCodes_1 = require("../../enums/exitCodes");
|
|
|
12
13
|
async function handleProjectCreationFlow(args) {
|
|
13
14
|
const { platformVersion, templateSource, projectBase, auth: providedAuth, distribution: providedDistribution, } = args;
|
|
14
15
|
const repo = templateSource || constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH;
|
|
16
|
+
const projectNameAndDestPromptResponse = await (0, projectNameAndDestPrompt_1.projectNameAndDestPrompt)(args);
|
|
15
17
|
if ((0, buildAndDeploy_1.useV3Api)(platformVersion)) {
|
|
16
18
|
const { componentTemplateChoices, authType, distribution, repoConfig, projectContents, } = await (0, v3_1.v3ComponentFlow)(platformVersion, projectBase, providedAuth, providedDistribution);
|
|
17
|
-
const
|
|
19
|
+
const selectProjectTemplatePromptResponse = await (0, selectProjectTemplatePrompt_1.selectProjectTemplatePrompt)(args, undefined, projectContents !== v3_1.EMPTY_PROJECT ? componentTemplateChoices : undefined);
|
|
18
20
|
return {
|
|
19
21
|
authType,
|
|
20
22
|
distribution,
|
|
21
23
|
repoConfig,
|
|
22
24
|
projectContents,
|
|
23
|
-
|
|
25
|
+
selectProjectTemplatePromptResponse,
|
|
26
|
+
projectNameAndDestPromptResponse,
|
|
24
27
|
};
|
|
25
28
|
}
|
|
26
29
|
const projectTemplates = await (0, legacy_1.getProjectTemplateListFromRepo)(repo, 'main');
|
|
@@ -28,6 +31,9 @@ async function handleProjectCreationFlow(args) {
|
|
|
28
31
|
logger_1.uiLogger.error(en_1.commands.project.create.errors.failedToFetchProjectList);
|
|
29
32
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
30
33
|
}
|
|
31
|
-
const
|
|
32
|
-
return {
|
|
34
|
+
const selectProjectTemplatePromptResponse = await (0, selectProjectTemplatePrompt_1.selectProjectTemplatePrompt)(args, projectTemplates);
|
|
35
|
+
return {
|
|
36
|
+
selectProjectTemplatePromptResponse,
|
|
37
|
+
projectNameAndDestPromptResponse,
|
|
38
|
+
};
|
|
33
39
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ComponentTemplate, ComponentTemplateChoice, ProjectTemplateRepoConfig } from '../../../types/Projects';
|
|
2
2
|
import { ProjectMetadata } from '@hubspot/project-parsing-lib/src/lib/project';
|
|
3
|
-
import {
|
|
3
|
+
import { SelectProjectTemplatePromptResponse } from '../../prompts/selectProjectTemplatePrompt';
|
|
4
4
|
export declare const EMPTY_PROJECT = "empty";
|
|
5
5
|
export declare const PROJECT_WITH_APP = "app";
|
|
6
6
|
export declare function createV3App(providedAuth: string | undefined, providedDistribution: string | undefined): Promise<{
|
|
@@ -16,8 +16,8 @@ type V3ComponentInfo = {
|
|
|
16
16
|
componentTemplateChoices?: ComponentTemplateChoice[];
|
|
17
17
|
};
|
|
18
18
|
export declare function v3ComponentFlow(platformVersion: string, projectBase: string | undefined, providedAuth: string | undefined, providedDistribution: string | undefined): Promise<V3ComponentInfo>;
|
|
19
|
-
export declare function generateComponentPaths({
|
|
20
|
-
|
|
19
|
+
export declare function generateComponentPaths({ selectProjectTemplatePromptResponse, platformVersion, repoConfig, projectContents, authType, distribution, }: {
|
|
20
|
+
selectProjectTemplatePromptResponse: SelectProjectTemplatePromptResponse;
|
|
21
21
|
platformVersion: string;
|
|
22
22
|
repoConfig?: ProjectTemplateRepoConfig;
|
|
23
23
|
projectContents?: string;
|
|
@@ -134,11 +134,11 @@ async function v3ComponentFlow(platformVersion, projectBase, providedAuth, provi
|
|
|
134
134
|
repoConfig,
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
|
-
function generateComponentPaths({
|
|
137
|
+
function generateComponentPaths({ selectProjectTemplatePromptResponse, platformVersion, repoConfig, projectContents, authType, distribution, }) {
|
|
138
138
|
if (!(0, buildAndDeploy_1.useV3Api)(platformVersion)) {
|
|
139
139
|
return [];
|
|
140
140
|
}
|
|
141
|
-
const components =
|
|
141
|
+
const components = selectProjectTemplatePromptResponse.componentTemplates?.map((componentTemplate) => {
|
|
142
142
|
return path_1.default.join(platformVersion, componentTemplate.path);
|
|
143
143
|
}) || [];
|
|
144
144
|
if (projectContents && projectContents !== exports.EMPTY_PROJECT) {
|
|
@@ -16,15 +16,16 @@ declare class LocalDevProcess {
|
|
|
16
16
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
17
17
|
};
|
|
18
18
|
get logger(): LocalDevLogger;
|
|
19
|
-
get configFilesUpdatedSinceLastUpload(): Set<string>;
|
|
20
19
|
private setupDevServers;
|
|
21
20
|
private startDevServers;
|
|
22
21
|
private cleanupDevServers;
|
|
23
22
|
private compareLocalProjectToDeployed;
|
|
24
23
|
private projectConfigValidForUpload;
|
|
24
|
+
private getIntermediateRepresentation;
|
|
25
25
|
private updateProjectNodes;
|
|
26
|
+
private updateProjectNodesAfterUpload;
|
|
26
27
|
handleFileChange(filePath: string, event: string): Promise<void>;
|
|
27
|
-
handleConfigFileChange(
|
|
28
|
+
handleConfigFileChange(): Promise<void>;
|
|
28
29
|
start(): Promise<void>;
|
|
29
30
|
stop(showProgress?: boolean): Promise<void>;
|
|
30
31
|
uploadProject(): Promise<boolean>;
|
|
@@ -46,9 +46,6 @@ class LocalDevProcess {
|
|
|
46
46
|
get logger() {
|
|
47
47
|
return this._logger;
|
|
48
48
|
}
|
|
49
|
-
get configFilesUpdatedSinceLastUpload() {
|
|
50
|
-
return this.state.configFilesUpdatedSinceLastUpload;
|
|
51
|
-
}
|
|
52
49
|
async setupDevServers() {
|
|
53
50
|
try {
|
|
54
51
|
await this.devServerManager.setup();
|
|
@@ -105,17 +102,28 @@ class LocalDevProcess {
|
|
|
105
102
|
});
|
|
106
103
|
return true;
|
|
107
104
|
}
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
getIntermediateRepresentation(projectNodesAtLastUpload) {
|
|
106
|
+
return (0, project_parsing_lib_1.translateForLocalDev)({
|
|
110
107
|
projectSourceDir: path_1.default.join(this.state.projectDir, this.state.projectConfig.srcDir),
|
|
111
108
|
platformVersion: this.state.projectConfig.platformVersion,
|
|
112
109
|
accountId: this.state.targetProjectAccountId,
|
|
113
110
|
}, {
|
|
114
|
-
|
|
111
|
+
projectNodesAtLastUpload,
|
|
112
|
+
profile: this.state.profile,
|
|
115
113
|
});
|
|
114
|
+
}
|
|
115
|
+
async updateProjectNodes() {
|
|
116
|
+
const intermediateRepresentation = await this.getIntermediateRepresentation(this.state.projectNodesAtLastUpload);
|
|
116
117
|
this.state.projectNodes =
|
|
117
118
|
intermediateRepresentation.intermediateNodesIndexedByUid;
|
|
118
119
|
}
|
|
120
|
+
async updateProjectNodesAfterUpload() {
|
|
121
|
+
const intermediateRepresentation = await this.getIntermediateRepresentation();
|
|
122
|
+
this.state.projectNodes =
|
|
123
|
+
intermediateRepresentation.intermediateNodesIndexedByUid;
|
|
124
|
+
this.state.projectNodesAtLastUpload =
|
|
125
|
+
intermediateRepresentation.intermediateNodesIndexedByUid;
|
|
126
|
+
}
|
|
119
127
|
async handleFileChange(filePath, event) {
|
|
120
128
|
await this.updateProjectNodes();
|
|
121
129
|
try {
|
|
@@ -125,10 +133,7 @@ class LocalDevProcess {
|
|
|
125
133
|
this.logger.fileChangeError(e);
|
|
126
134
|
}
|
|
127
135
|
}
|
|
128
|
-
async handleConfigFileChange(
|
|
129
|
-
if (event === 'add' || event === 'change') {
|
|
130
|
-
this.state.addUpdatedConfigFileUpdatedSinceLastUpload(filePath);
|
|
131
|
-
}
|
|
136
|
+
async handleConfigFileChange() {
|
|
132
137
|
await this.updateProjectNodes();
|
|
133
138
|
this.logger.uploadWarning();
|
|
134
139
|
}
|
|
@@ -185,8 +190,7 @@ class LocalDevProcess {
|
|
|
185
190
|
this.logger.uploadError(uploadError);
|
|
186
191
|
return false;
|
|
187
192
|
}
|
|
188
|
-
this.
|
|
189
|
-
this.updateProjectNodes();
|
|
193
|
+
await this.updateProjectNodesAfterUpload();
|
|
190
194
|
this.logger.uploadSuccess();
|
|
191
195
|
this.logger.clearUploadWarnings();
|
|
192
196
|
return true;
|
|
@@ -6,6 +6,7 @@ import { LocalDevStateConstructorOptions, LocalDevStateListener, AppLocalDevData
|
|
|
6
6
|
declare class LocalDevState {
|
|
7
7
|
private _targetProjectAccountId;
|
|
8
8
|
private _targetTestingAccountId;
|
|
9
|
+
private _profile?;
|
|
9
10
|
private _projectConfig;
|
|
10
11
|
private _projectDir;
|
|
11
12
|
private _projectId;
|
|
@@ -14,15 +15,16 @@ declare class LocalDevState {
|
|
|
14
15
|
private _deployedBuild?;
|
|
15
16
|
private _isGithubLinked;
|
|
16
17
|
private _projectNodes;
|
|
18
|
+
private _projectNodesAtLastUpload;
|
|
17
19
|
private _env;
|
|
18
20
|
private _listeners;
|
|
19
|
-
private _configFilesUpdatedSinceLastUpload;
|
|
20
21
|
private _appData;
|
|
21
22
|
private _devServerMessage;
|
|
22
|
-
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectId, projectName, debug, deployedBuild, isGithubLinked, initialProjectNodes, env, }: LocalDevStateConstructorOptions);
|
|
23
|
+
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectId, projectName, debug, deployedBuild, isGithubLinked, initialProjectNodes, profile, env, }: LocalDevStateConstructorOptions);
|
|
23
24
|
private runListeners;
|
|
24
25
|
get targetProjectAccountId(): number;
|
|
25
26
|
get targetTestingAccountId(): number;
|
|
27
|
+
get profile(): string | undefined;
|
|
26
28
|
get projectConfig(): ProjectConfig;
|
|
27
29
|
get projectDir(): string;
|
|
28
30
|
get projectId(): number;
|
|
@@ -36,10 +38,13 @@ declare class LocalDevState {
|
|
|
36
38
|
set projectNodes(nodes: {
|
|
37
39
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
38
40
|
});
|
|
41
|
+
get projectNodesAtLastUpload(): {
|
|
42
|
+
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
43
|
+
};
|
|
44
|
+
set projectNodesAtLastUpload(nodes: {
|
|
45
|
+
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
46
|
+
});
|
|
39
47
|
get env(): Environment;
|
|
40
|
-
get configFilesUpdatedSinceLastUpload(): Set<string>;
|
|
41
|
-
addUpdatedConfigFileUpdatedSinceLastUpload(filePath: string): void;
|
|
42
|
-
resetConfigFilesUpdatedSinceLastUpload(): void;
|
|
43
48
|
get appData(): Record<string, AppLocalDevData>;
|
|
44
49
|
getAppDataByUid(uid: string): AppLocalDevData | undefined;
|
|
45
50
|
setAppDataForUid(uid: string, appData: AppLocalDevData): void;
|
|
@@ -4,6 +4,7 @@ const constants_1 = require("../../constants");
|
|
|
4
4
|
class LocalDevState {
|
|
5
5
|
_targetProjectAccountId;
|
|
6
6
|
_targetTestingAccountId;
|
|
7
|
+
_profile;
|
|
7
8
|
_projectConfig;
|
|
8
9
|
_projectDir;
|
|
9
10
|
_projectId;
|
|
@@ -12,14 +13,15 @@ class LocalDevState {
|
|
|
12
13
|
_deployedBuild;
|
|
13
14
|
_isGithubLinked;
|
|
14
15
|
_projectNodes;
|
|
16
|
+
_projectNodesAtLastUpload;
|
|
15
17
|
_env;
|
|
16
18
|
_listeners;
|
|
17
|
-
_configFilesUpdatedSinceLastUpload;
|
|
18
19
|
_appData;
|
|
19
20
|
_devServerMessage;
|
|
20
|
-
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectId, projectName, debug, deployedBuild, isGithubLinked, initialProjectNodes, env, }) {
|
|
21
|
+
constructor({ targetProjectAccountId, targetTestingAccountId, projectConfig, projectDir, projectId, projectName, debug, deployedBuild, isGithubLinked, initialProjectNodes, profile, env, }) {
|
|
21
22
|
this._targetProjectAccountId = targetProjectAccountId;
|
|
22
23
|
this._targetTestingAccountId = targetTestingAccountId;
|
|
24
|
+
this._profile = profile;
|
|
23
25
|
this._projectConfig = projectConfig;
|
|
24
26
|
this._projectDir = projectDir;
|
|
25
27
|
this._projectId = projectId;
|
|
@@ -28,8 +30,8 @@ class LocalDevState {
|
|
|
28
30
|
this._deployedBuild = deployedBuild;
|
|
29
31
|
this._isGithubLinked = isGithubLinked;
|
|
30
32
|
this._projectNodes = initialProjectNodes;
|
|
33
|
+
this._projectNodesAtLastUpload = initialProjectNodes;
|
|
31
34
|
this._env = env;
|
|
32
|
-
this._configFilesUpdatedSinceLastUpload = new Set();
|
|
33
35
|
this._appData = {};
|
|
34
36
|
this._devServerMessage = constants_1.LOCAL_DEV_SERVER_MESSAGE_TYPES.INITIAL;
|
|
35
37
|
this._listeners = {};
|
|
@@ -45,10 +47,11 @@ class LocalDevState {
|
|
|
45
47
|
get targetTestingAccountId() {
|
|
46
48
|
return this._targetTestingAccountId;
|
|
47
49
|
}
|
|
50
|
+
get profile() {
|
|
51
|
+
return this._profile;
|
|
52
|
+
}
|
|
48
53
|
get projectConfig() {
|
|
49
|
-
return
|
|
50
|
-
...this._projectConfig,
|
|
51
|
-
};
|
|
54
|
+
return structuredClone(this._projectConfig);
|
|
52
55
|
}
|
|
53
56
|
get projectDir() {
|
|
54
57
|
return this._projectDir;
|
|
@@ -63,34 +66,29 @@ class LocalDevState {
|
|
|
63
66
|
return this._debug;
|
|
64
67
|
}
|
|
65
68
|
get deployedBuild() {
|
|
66
|
-
return
|
|
67
|
-
...this._deployedBuild,
|
|
68
|
-
});
|
|
69
|
+
return this._deployedBuild && structuredClone(this._deployedBuild);
|
|
69
70
|
}
|
|
70
71
|
get isGithubLinked() {
|
|
71
72
|
return this._isGithubLinked;
|
|
72
73
|
}
|
|
73
74
|
get projectNodes() {
|
|
74
|
-
return
|
|
75
|
+
return structuredClone(this._projectNodes);
|
|
75
76
|
}
|
|
76
77
|
set projectNodes(nodes) {
|
|
77
78
|
this._projectNodes = nodes;
|
|
78
79
|
this.runListeners('projectNodes');
|
|
79
80
|
}
|
|
80
|
-
get
|
|
81
|
-
return this.
|
|
82
|
-
}
|
|
83
|
-
get configFilesUpdatedSinceLastUpload() {
|
|
84
|
-
return this._configFilesUpdatedSinceLastUpload;
|
|
81
|
+
get projectNodesAtLastUpload() {
|
|
82
|
+
return structuredClone(this._projectNodesAtLastUpload);
|
|
85
83
|
}
|
|
86
|
-
|
|
87
|
-
this.
|
|
84
|
+
set projectNodesAtLastUpload(nodes) {
|
|
85
|
+
this._projectNodesAtLastUpload = nodes;
|
|
88
86
|
}
|
|
89
|
-
|
|
90
|
-
this.
|
|
87
|
+
get env() {
|
|
88
|
+
return this._env;
|
|
91
89
|
}
|
|
92
90
|
get appData() {
|
|
93
|
-
return
|
|
91
|
+
return structuredClone(this._appData);
|
|
94
92
|
}
|
|
95
93
|
getAppDataByUid(uid) {
|
|
96
94
|
return { ...this._appData[uid] };
|
|
@@ -21,7 +21,7 @@ class LocalDevWatcher {
|
|
|
21
21
|
}
|
|
22
22
|
handleWatchEvent(filePath, event, configPaths) {
|
|
23
23
|
if (configPaths.includes(filePath)) {
|
|
24
|
-
return this.localDevProcess.handleConfigFileChange(
|
|
24
|
+
return this.localDevProcess.handleConfigFileChange();
|
|
25
25
|
}
|
|
26
26
|
return this.localDevProcess.handleFileChange(filePath, event);
|
|
27
27
|
}
|
|
@@ -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;
|
package/lib/projects/upload.d.ts
CHANGED
|
@@ -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<
|
|
24
|
+
export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<IntermediateRepresentation | undefined>;
|
|
24
25
|
export {};
|
package/lib/projects/upload.js
CHANGED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { PromptOptionsArg, ProjectNameAndDestPromptResponse } from './selectProjectTemplatePrompt';
|
|
2
|
+
export declare function projectNameAndDestPrompt(promptOptions: PromptOptionsArg): Promise<ProjectNameAndDestPromptResponse>;
|
|
3
|
+
export declare function validateProjectDirectory(input?: string): string | boolean;
|
|
@@ -0,0 +1,60 @@
|
|
|
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.projectNameAndDestPrompt = projectNameAndDestPrompt;
|
|
7
|
+
exports.validateProjectDirectory = validateProjectDirectory;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
11
|
+
const en_1 = require("../../lang/en");
|
|
12
|
+
const promptUtils_1 = require("./promptUtils");
|
|
13
|
+
const constants_1 = require("../constants");
|
|
14
|
+
async function projectNameAndDestPrompt(promptOptions) {
|
|
15
|
+
const result = await (0, promptUtils_1.promptUser)([
|
|
16
|
+
{
|
|
17
|
+
name: 'name',
|
|
18
|
+
message: en_1.lib.prompts.projectNameAndDestPrompt.enterName,
|
|
19
|
+
when: !promptOptions.name,
|
|
20
|
+
validate: (input) => {
|
|
21
|
+
if (!input) {
|
|
22
|
+
return en_1.lib.prompts.projectNameAndDestPrompt.errors.nameRequired;
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'dest',
|
|
29
|
+
message: en_1.lib.prompts.projectNameAndDestPrompt.enterDest,
|
|
30
|
+
when: !promptOptions.dest,
|
|
31
|
+
default: answers => {
|
|
32
|
+
const projectName = (0, path_2.sanitizeFileName)(promptOptions.name || answers.name);
|
|
33
|
+
return path_1.default.resolve((0, path_2.getCwd)(), projectName);
|
|
34
|
+
},
|
|
35
|
+
validate: validateProjectDirectory,
|
|
36
|
+
filter: input => {
|
|
37
|
+
return (0, path_2.untildify)(input);
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
]);
|
|
41
|
+
if (!result.name) {
|
|
42
|
+
result.name = promptOptions.name;
|
|
43
|
+
}
|
|
44
|
+
if (!result.dest) {
|
|
45
|
+
result.dest = promptOptions.dest;
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
function validateProjectDirectory(input) {
|
|
50
|
+
if (!input) {
|
|
51
|
+
return en_1.lib.prompts.projectNameAndDestPrompt.errors.destRequired;
|
|
52
|
+
}
|
|
53
|
+
if (fs_1.default.existsSync(path_1.default.resolve((0, path_2.getCwd)(), path_1.default.join(input, constants_1.PROJECT_CONFIG_FILE)))) {
|
|
54
|
+
return en_1.lib.prompts.projectNameAndDestPrompt.errors.invalidDest;
|
|
55
|
+
}
|
|
56
|
+
if (!(0, path_2.isValidPath)(input)) {
|
|
57
|
+
return en_1.lib.prompts.projectNameAndDestPrompt.errors.invalidCharacters;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ComponentTemplate, ComponentTemplateChoice, ProjectTemplate } from '../../types/Projects';
|
|
2
|
+
export type SelectProjectTemplatePromptResponse = {
|
|
3
|
+
projectTemplate?: ProjectTemplate;
|
|
4
|
+
componentTemplates?: ComponentTemplate[];
|
|
5
|
+
};
|
|
6
|
+
type SelectProjectTemplatePromptResponseProjectTemplate = {
|
|
7
|
+
projectTemplate: ProjectTemplate;
|
|
8
|
+
componentTemplates: undefined;
|
|
9
|
+
};
|
|
10
|
+
type SelectProjectTemplatePromptResponseComponentTemplates = {
|
|
11
|
+
projectTemplate?: undefined;
|
|
12
|
+
componentTemplates?: ComponentTemplate[];
|
|
13
|
+
};
|
|
14
|
+
export type ProjectNameAndDestPromptResponse = {
|
|
15
|
+
name: string;
|
|
16
|
+
dest: string;
|
|
17
|
+
};
|
|
18
|
+
export type PromptOptionsArg = {
|
|
19
|
+
name?: string;
|
|
20
|
+
dest?: string;
|
|
21
|
+
template?: string;
|
|
22
|
+
features?: string[];
|
|
23
|
+
};
|
|
24
|
+
export declare function selectProjectTemplatePrompt(promptOptions: PromptOptionsArg, projectTemplates?: ProjectTemplate[], componentTemplates?: undefined): Promise<SelectProjectTemplatePromptResponseProjectTemplate>;
|
|
25
|
+
export declare function selectProjectTemplatePrompt(promptOptions: PromptOptionsArg, projectTemplates?: undefined, componentTemplates?: ComponentTemplateChoice[]): Promise<SelectProjectTemplatePromptResponseComponentTemplates>;
|
|
26
|
+
export {};
|
|
@@ -1,31 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
3
|
+
exports.selectProjectTemplatePrompt = selectProjectTemplatePrompt;
|
|
10
4
|
const promptUtils_1 = require("./promptUtils");
|
|
11
|
-
const constants_1 = require("../constants");
|
|
12
5
|
const en_1 = require("../../lang/en");
|
|
13
|
-
function validateProjectDirectory(input) {
|
|
14
|
-
if (!input) {
|
|
15
|
-
return en_1.lib.prompts.createProjectPrompt.errors.destRequired;
|
|
16
|
-
}
|
|
17
|
-
if (fs_1.default.existsSync(path_1.default.resolve((0, path_2.getCwd)(), path_1.default.join(input, constants_1.PROJECT_CONFIG_FILE)))) {
|
|
18
|
-
return en_1.lib.prompts.createProjectPrompt.errors.invalidDest;
|
|
19
|
-
}
|
|
20
|
-
if (!(0, path_2.isValidPath)(input)) {
|
|
21
|
-
return en_1.lib.prompts.createProjectPrompt.errors.invalidCharacters;
|
|
22
|
-
}
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
6
|
function findTemplateByNameOrLabel(projectTemplates, templateNameOrLabel) {
|
|
26
7
|
return projectTemplates.find(t => t.name === templateNameOrLabel || t.label === templateNameOrLabel);
|
|
27
8
|
}
|
|
28
|
-
async function
|
|
9
|
+
async function selectProjectTemplatePrompt(promptOptions, projectTemplates, componentTemplates) {
|
|
29
10
|
const createProjectFromTemplate = !!projectTemplates && projectTemplates.length > 0;
|
|
30
11
|
const createProjectFromComponents = Array.isArray(componentTemplates) && componentTemplates?.length > 0;
|
|
31
12
|
const selectedComponents = [];
|
|
@@ -46,36 +27,12 @@ async function createProjectPrompt(promptOptions, projectTemplates, componentTem
|
|
|
46
27
|
!!promptOptions.template &&
|
|
47
28
|
!!findTemplateByNameOrLabel(projectTemplates, promptOptions.template);
|
|
48
29
|
const result = await (0, promptUtils_1.promptUser)([
|
|
49
|
-
{
|
|
50
|
-
name: 'name',
|
|
51
|
-
message: en_1.lib.prompts.createProjectPrompt.enterName,
|
|
52
|
-
when: !promptOptions.name,
|
|
53
|
-
validate: (input) => {
|
|
54
|
-
if (!input) {
|
|
55
|
-
return en_1.lib.prompts.createProjectPrompt.errors.nameRequired;
|
|
56
|
-
}
|
|
57
|
-
return true;
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: 'dest',
|
|
62
|
-
message: en_1.lib.prompts.createProjectPrompt.enterDest,
|
|
63
|
-
when: !promptOptions.dest,
|
|
64
|
-
default: answers => {
|
|
65
|
-
const projectName = (0, path_2.sanitizeFileName)(promptOptions.name || answers.name);
|
|
66
|
-
return path_1.default.resolve((0, path_2.getCwd)(), projectName);
|
|
67
|
-
},
|
|
68
|
-
validate: validateProjectDirectory,
|
|
69
|
-
filter: input => {
|
|
70
|
-
return (0, path_2.untildify)(input);
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
30
|
{
|
|
74
31
|
name: 'projectTemplate',
|
|
75
32
|
message: () => {
|
|
76
33
|
return promptOptions.template && !providedTemplateIsValid
|
|
77
|
-
? en_1.lib.prompts.
|
|
78
|
-
: en_1.lib.prompts.
|
|
34
|
+
? en_1.lib.prompts.selectProjectTemplatePrompt.errors.invalidTemplate(promptOptions.template)
|
|
35
|
+
: en_1.lib.prompts.selectProjectTemplatePrompt.selectTemplate;
|
|
79
36
|
},
|
|
80
37
|
when: createProjectFromTemplate && !providedTemplateIsValid,
|
|
81
38
|
type: 'list',
|
|
@@ -90,7 +47,7 @@ async function createProjectPrompt(promptOptions, projectTemplates, componentTem
|
|
|
90
47
|
},
|
|
91
48
|
{
|
|
92
49
|
name: 'componentTemplates',
|
|
93
|
-
message: en_1.lib.prompts.
|
|
50
|
+
message: en_1.lib.prompts.selectProjectTemplatePrompt.features,
|
|
94
51
|
when: !promptOptions.features &&
|
|
95
52
|
createProjectFromComponents &&
|
|
96
53
|
selectedComponents.length === 0,
|
|
@@ -98,12 +55,6 @@ async function createProjectPrompt(promptOptions, projectTemplates, componentTem
|
|
|
98
55
|
choices: componentTemplates,
|
|
99
56
|
},
|
|
100
57
|
]);
|
|
101
|
-
if (!result.name) {
|
|
102
|
-
result.name = promptOptions.name;
|
|
103
|
-
}
|
|
104
|
-
if (!result.dest) {
|
|
105
|
-
result.dest = promptOptions.dest;
|
|
106
|
-
}
|
|
107
58
|
if (!result.componentTemplates) {
|
|
108
59
|
result.componentTemplates = selectedComponents;
|
|
109
60
|
}
|
|
@@ -112,7 +63,7 @@ async function createProjectPrompt(promptOptions, projectTemplates, componentTem
|
|
|
112
63
|
}
|
|
113
64
|
if (projectTemplates && projectTemplates.length > 0) {
|
|
114
65
|
if (!result.projectTemplate) {
|
|
115
|
-
throw new Error(en_1.lib.prompts.
|
|
66
|
+
throw new Error(en_1.lib.prompts.selectProjectTemplatePrompt.errors.projectTemplateRequired);
|
|
116
67
|
}
|
|
117
68
|
return result;
|
|
118
69
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "7.7.16-experimental.
|
|
3
|
+
"version": "7.7.16-experimental.5",
|
|
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
8
|
"@hubspot/local-dev-lib": "3.11.0",
|
|
9
|
-
"@hubspot/project-parsing-lib": "0.
|
|
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",
|
|
12
12
|
"@hubspot/ui-extensions-dev-server": "0.9.2",
|
package/types/LocalDev.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { APP_INSTALLATION_STATES, LOCAL_DEV_SERVER_MESSAGE_TYPES } from '../lib/
|
|
|
8
8
|
export type LocalDevStateConstructorOptions = {
|
|
9
9
|
targetProjectAccountId: number;
|
|
10
10
|
targetTestingAccountId: number;
|
|
11
|
+
profile?: string;
|
|
11
12
|
projectConfig: ProjectConfig;
|
|
12
13
|
projectDir: string;
|
|
13
14
|
projectId: number;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { ComponentTemplate, ComponentTemplateChoice, ProjectTemplate } from '../../types/Projects';
|
|
2
|
-
export type CreateProjectPromptResponse = {
|
|
3
|
-
name: string;
|
|
4
|
-
dest: string;
|
|
5
|
-
projectTemplate?: ProjectTemplate;
|
|
6
|
-
componentTemplates?: ComponentTemplate[];
|
|
7
|
-
};
|
|
8
|
-
type CreateProjectPromptResponseProjectTemplate = {
|
|
9
|
-
name: string;
|
|
10
|
-
dest: string;
|
|
11
|
-
projectTemplate: ProjectTemplate;
|
|
12
|
-
componentTemplates: undefined;
|
|
13
|
-
};
|
|
14
|
-
type CreateProjectPromptResponseComponentTemplates = {
|
|
15
|
-
name: string;
|
|
16
|
-
dest: string;
|
|
17
|
-
projectTemplate?: undefined;
|
|
18
|
-
componentTemplates?: ComponentTemplate[];
|
|
19
|
-
};
|
|
20
|
-
type PromptOptionsArg = {
|
|
21
|
-
name?: string;
|
|
22
|
-
dest?: string;
|
|
23
|
-
template?: string;
|
|
24
|
-
features?: string[];
|
|
25
|
-
};
|
|
26
|
-
export declare function createProjectPrompt(promptOptions: PromptOptionsArg, projectTemplates?: ProjectTemplate[], componentTemplates?: undefined): Promise<CreateProjectPromptResponseProjectTemplate>;
|
|
27
|
-
export declare function createProjectPrompt(promptOptions: PromptOptionsArg, projectTemplates?: undefined, componentTemplates?: ComponentTemplateChoice[]): Promise<CreateProjectPromptResponseComponentTemplates>;
|
|
28
|
-
export {};
|