@hubspot/cli 7.0.15-experimental.0 → 7.0.16-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/commands/create/api-sample.js +14 -4
- package/commands/project/add.js +62 -16
- package/commands/project/cloneApp.js +3 -3
- package/commands/project/create.js +70 -15
- package/commands/project/migrateApp.js +3 -3
- package/commands/project/upload.js +2 -7
- package/lang/en.lyaml +20 -12
- package/lib/projects/create.d.ts +5 -0
- package/lib/projects/create.js +51 -0
- package/lib/projects/index.d.ts +1 -5
- package/lib/projects/index.js +1 -62
- package/lib/projects/upload.d.ts +1 -1
- package/lib/projects/upload.js +2 -2
- package/lib/prompts/createProjectPrompt.d.ts +6 -8
- package/lib/prompts/createProjectPrompt.js +26 -54
- package/lib/prompts/projectAddPrompt.d.ts +3 -3
- package/lib/prompts/projectAddPrompt.js +16 -6
- package/package.json +2 -2
- package/types/Projects.d.ts +1 -6
|
@@ -6,8 +6,11 @@ const { confirmPrompt } = require('../../lib/prompts/promptUtils');
|
|
|
6
6
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const fs = require('fs-extra');
|
|
9
|
-
const {
|
|
9
|
+
const { fetchRepoFile } = require('@hubspot/local-dev-lib/api/github');
|
|
10
|
+
const { cloneGithubRepo } = require('@hubspot/local-dev-lib/github');
|
|
10
11
|
const { i18n } = require('../../lib/lang');
|
|
12
|
+
const { debugError } = require('../../lib/errorHandlers');
|
|
13
|
+
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
11
14
|
const i18nKey = 'commands.create.subcommands.apiSample';
|
|
12
15
|
module.exports = {
|
|
13
16
|
hidden: true,
|
|
@@ -30,15 +33,22 @@ module.exports = {
|
|
|
30
33
|
return;
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
|
-
|
|
36
|
+
let samplesConfig;
|
|
37
|
+
try {
|
|
38
|
+
const { data } = await fetchRepoFile('HubSpot/sample-apps-list', 'samples.json', 'main');
|
|
39
|
+
samplesConfig = data;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
debugError(err);
|
|
43
|
+
}
|
|
34
44
|
if (!samplesConfig) {
|
|
35
45
|
logger.error(i18n(`${i18nKey}.errors.noSamples`));
|
|
36
|
-
|
|
46
|
+
process.exit(EXIT_CODES.ERROR);
|
|
37
47
|
}
|
|
38
48
|
const { sampleType, sampleLanguage } = await createApiSamplePrompt(samplesConfig);
|
|
39
49
|
if (!sampleType || !sampleLanguage) {
|
|
40
50
|
logger.error(i18n(`${i18nKey}.errors.noSamples`));
|
|
41
|
-
|
|
51
|
+
process.exit(EXIT_CODES.ERROR);
|
|
42
52
|
}
|
|
43
53
|
logger.info(i18n(`${i18nKey}.info.sampleChosen`, {
|
|
44
54
|
sampleType,
|
package/commands/project/add.js
CHANGED
|
@@ -1,42 +1,88 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
// @ts-nocheck
|
|
4
|
+
const path = require('path');
|
|
4
5
|
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
6
|
+
const { cloneGithubRepo, fetchReleaseData, } = require('@hubspot/local-dev-lib/github');
|
|
7
|
+
const { debugError } = require('../../lib/errorHandlers');
|
|
7
8
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
8
9
|
const { i18n } = require('../../lib/lang');
|
|
9
10
|
const { projectAddPrompt } = require('../../lib/prompts/projectAddPrompt');
|
|
10
|
-
const {
|
|
11
|
+
const { getProjectConfig } = require('../../lib/projects');
|
|
12
|
+
const { getProjectComponentListFromRepo, } = require('../../lib/projects/create');
|
|
13
|
+
const { findProjectComponents } = require('../../lib/projects/structure');
|
|
14
|
+
const { ComponentTypes } = require('../../types/Projects');
|
|
11
15
|
const { uiBetaTag } = require('../../lib/ui');
|
|
12
16
|
const { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, } = require('../../lib/constants');
|
|
17
|
+
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
13
18
|
const i18nKey = 'commands.project.subcommands.add';
|
|
14
19
|
exports.command = 'add';
|
|
15
20
|
exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
|
|
16
21
|
exports.handler = async (options) => {
|
|
17
22
|
const { derivedAccountId } = options;
|
|
23
|
+
trackCommandUsage('project-add', null, derivedAccountId);
|
|
24
|
+
const { projectConfig, projectDir } = await getProjectConfig();
|
|
25
|
+
if (!projectDir || !projectConfig) {
|
|
26
|
+
logger.error(i18n(`${i18nKey}.error.locationInProject`));
|
|
27
|
+
process.exit(EXIT_CODES.ERROR);
|
|
28
|
+
}
|
|
29
|
+
// We currently only support adding private apps to projects
|
|
30
|
+
let projectContainsPublicApp = false;
|
|
31
|
+
try {
|
|
32
|
+
const components = await findProjectComponents(projectDir);
|
|
33
|
+
projectContainsPublicApp = components.some(c => c.type === ComponentTypes.PublicApp);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
debugError(err);
|
|
37
|
+
}
|
|
38
|
+
if (projectContainsPublicApp) {
|
|
39
|
+
logger.error(i18n(`${i18nKey}.error.projectContainsPublicApp`));
|
|
40
|
+
process.exit(EXIT_CODES.ERROR);
|
|
41
|
+
}
|
|
18
42
|
logger.log('');
|
|
19
|
-
logger.log(i18n(`${i18nKey}.creatingComponent
|
|
43
|
+
logger.log(i18n(`${i18nKey}.creatingComponent`, {
|
|
44
|
+
projectName: projectConfig.name,
|
|
45
|
+
}));
|
|
20
46
|
logger.log('');
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
47
|
+
let latestRepoReleaseTag;
|
|
48
|
+
try {
|
|
49
|
+
// We want the tag_name from the latest release of the components repo
|
|
50
|
+
const repoReleaseData = await fetchReleaseData(HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH);
|
|
51
|
+
if (repoReleaseData) {
|
|
52
|
+
latestRepoReleaseTag = repoReleaseData.tag_name;
|
|
53
|
+
}
|
|
28
54
|
}
|
|
29
|
-
|
|
55
|
+
catch (err) {
|
|
56
|
+
debugError(err);
|
|
57
|
+
}
|
|
58
|
+
if (!latestRepoReleaseTag) {
|
|
59
|
+
logger.error(i18n(`${i18nKey}.error.failedToFetchComponentList`));
|
|
60
|
+
process.exit(EXIT_CODES.ERROR);
|
|
61
|
+
}
|
|
62
|
+
const components = await getProjectComponentListFromRepo(latestRepoReleaseTag);
|
|
63
|
+
if (!components.length) {
|
|
64
|
+
logger.error(i18n(`${i18nKey}.error.failedToFetchComponentList`));
|
|
65
|
+
process.exit(EXIT_CODES.ERROR);
|
|
66
|
+
}
|
|
67
|
+
const projectAddPromptResponse = await projectAddPrompt(components, options);
|
|
30
68
|
try {
|
|
31
|
-
|
|
69
|
+
const componentPath = path.join(projectDir, projectConfig.srcDir, projectAddPromptResponse.componentTemplate.insertPath, projectAddPromptResponse.name);
|
|
70
|
+
await cloneGithubRepo(HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, componentPath, {
|
|
71
|
+
sourceDir: projectAddPromptResponse.componentTemplate.path,
|
|
72
|
+
tag: latestRepoReleaseTag,
|
|
73
|
+
hideLogs: true,
|
|
74
|
+
});
|
|
32
75
|
logger.log('');
|
|
33
|
-
logger.
|
|
34
|
-
componentName: name,
|
|
76
|
+
logger.success(i18n(`${i18nKey}.success`, {
|
|
77
|
+
componentName: projectAddPromptResponse.name,
|
|
35
78
|
}));
|
|
36
79
|
}
|
|
37
80
|
catch (error) {
|
|
38
|
-
|
|
81
|
+
debugError(error);
|
|
82
|
+
logger.error(i18n(`${i18nKey}.error.failedToDownloadComponent`));
|
|
83
|
+
process.exit(EXIT_CODES.ERROR);
|
|
39
84
|
}
|
|
85
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
40
86
|
};
|
|
41
87
|
exports.builder = yargs => {
|
|
42
88
|
yargs.options({
|
|
@@ -53,9 +53,9 @@ exports.handler = async (options) => {
|
|
|
53
53
|
});
|
|
54
54
|
appId = appIdResponse.appId;
|
|
55
55
|
}
|
|
56
|
-
const
|
|
57
|
-
projectName = name;
|
|
58
|
-
projectDest =
|
|
56
|
+
const createProjectPromptResponse = await createProjectPrompt(options);
|
|
57
|
+
projectName = createProjectPromptResponse.name;
|
|
58
|
+
projectDest = createProjectPromptResponse.dest;
|
|
59
59
|
}
|
|
60
60
|
catch (error) {
|
|
61
61
|
logError(error, new ApiErrorContext({ accountId: derivedAccountId }));
|
|
@@ -1,32 +1,86 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
// @ts-nocheck
|
|
4
|
-
const { addAccountOptions, addConfigOptions, addUseEnvironmentOptions, } = require('../../lib/commonOpts');
|
|
5
|
-
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
6
|
-
const { getCwd } = require('@hubspot/local-dev-lib/path');
|
|
7
4
|
const path = require('path');
|
|
5
|
+
const fs = require('fs-extra');
|
|
8
6
|
const chalk = require('chalk');
|
|
7
|
+
const { logger } = require('@hubspot/local-dev-lib/logger');
|
|
8
|
+
const { fetchReleaseData, cloneGithubRepo, } = require('@hubspot/local-dev-lib/github');
|
|
9
|
+
const { getCwd } = require('@hubspot/local-dev-lib/path');
|
|
10
|
+
const { addAccountOptions, addConfigOptions, addUseEnvironmentOptions, } = require('../../lib/commonOpts');
|
|
11
|
+
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
9
12
|
const { createProjectPrompt, } = require('../../lib/prompts/createProjectPrompt');
|
|
10
|
-
const {
|
|
13
|
+
const { writeProjectConfig, getProjectConfig } = require('../../lib/projects');
|
|
14
|
+
const { getProjectTemplateListFromRepo, EMPTY_PROJECT_TEMPLATE_NAME, } = require('../../lib/projects/create');
|
|
11
15
|
const { i18n } = require('../../lib/lang');
|
|
12
16
|
const { uiBetaTag, uiFeatureHighlight } = require('../../lib/ui');
|
|
13
|
-
const {
|
|
14
|
-
const {
|
|
15
|
-
const {
|
|
17
|
+
const { debugError } = require('../../lib/errorHandlers');
|
|
18
|
+
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
19
|
+
const { PROJECT_CONFIG_FILE, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, DEFAULT_PROJECT_TEMPLATE_BRANCH, } = require('../../lib/constants');
|
|
16
20
|
const i18nKey = 'commands.project.subcommands.create';
|
|
17
21
|
exports.command = 'create';
|
|
18
22
|
exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
|
|
19
23
|
exports.handler = async (options) => {
|
|
20
24
|
const { derivedAccountId } = options;
|
|
21
|
-
|
|
22
|
-
let
|
|
23
|
-
if (!
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
let latestRepoReleaseTag;
|
|
26
|
+
let templateSource = options.templateSource;
|
|
27
|
+
if (!templateSource) {
|
|
28
|
+
templateSource = HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH;
|
|
29
|
+
try {
|
|
30
|
+
const releaseData = await fetchReleaseData(HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH);
|
|
31
|
+
if (releaseData) {
|
|
32
|
+
latestRepoReleaseTag = releaseData.tag_name;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
logger.error(i18n(`${i18nKey}.error.failedToFetchProjectList`));
|
|
37
|
+
process.exit(EXIT_CODES.ERROR);
|
|
38
|
+
}
|
|
26
39
|
}
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
40
|
+
const projectTemplates = await getProjectTemplateListFromRepo(templateSource, latestRepoReleaseTag || DEFAULT_PROJECT_TEMPLATE_BRANCH);
|
|
41
|
+
if (!projectTemplates.length) {
|
|
42
|
+
logger.error(i18n(`${i18nKey}.error.failedToFetchProjectList`));
|
|
43
|
+
process.exit(EXIT_CODES.ERROR);
|
|
44
|
+
}
|
|
45
|
+
const createProjectPromptResponse = await createProjectPrompt(options, projectTemplates);
|
|
46
|
+
const projectDest = path.resolve(getCwd(), createProjectPromptResponse.dest);
|
|
47
|
+
trackCommandUsage('project-create', { type: createProjectPromptResponse.projectTemplate.name }, derivedAccountId);
|
|
48
|
+
const { projectConfig: existingProjectConfig, projectDir: existingProjectDir, } = await getProjectConfig(projectDest);
|
|
49
|
+
// Exit if the target destination is within an existing project
|
|
50
|
+
if (existingProjectConfig && projectDest.startsWith(existingProjectDir)) {
|
|
51
|
+
logger.error(i18n(`${i18nKey}.errors.cannotNestProjects`, {
|
|
52
|
+
projectDir: existingProjectDir,
|
|
53
|
+
}));
|
|
54
|
+
process.exit(EXIT_CODES.ERROR);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
await cloneGithubRepo(templateSource, projectDest, {
|
|
58
|
+
sourceDir: createProjectPromptResponse.projectTemplate.path,
|
|
59
|
+
tag: latestRepoReleaseTag,
|
|
60
|
+
hideLogs: true,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
debugError(err);
|
|
65
|
+
logger.error(i18n(`${i18nKey}.errors.failedToDownloadProject`));
|
|
66
|
+
process.exit(EXIT_CODES.ERROR);
|
|
67
|
+
}
|
|
68
|
+
const projectConfigPath = path.join(projectDest, PROJECT_CONFIG_FILE);
|
|
69
|
+
const parsedConfigFile = JSON.parse(fs.readFileSync(projectConfigPath).toString());
|
|
70
|
+
writeProjectConfig(projectConfigPath, {
|
|
71
|
+
...parsedConfigFile,
|
|
72
|
+
name: createProjectPromptResponse.name,
|
|
73
|
+
});
|
|
74
|
+
// If the template is 'no-template', we need to manually create a src directory
|
|
75
|
+
if (createProjectPromptResponse.projectTemplate.name ===
|
|
76
|
+
EMPTY_PROJECT_TEMPLATE_NAME) {
|
|
77
|
+
fs.ensureDirSync(path.join(projectDest, 'src'));
|
|
78
|
+
}
|
|
79
|
+
logger.log('');
|
|
80
|
+
logger.success(i18n(`${i18nKey}.logs.success`, {
|
|
81
|
+
projectName: createProjectPromptResponse.name,
|
|
82
|
+
projectDest,
|
|
83
|
+
}));
|
|
30
84
|
logger.log('');
|
|
31
85
|
logger.log(chalk.bold(i18n(`${i18nKey}.logs.welcomeMessage`)));
|
|
32
86
|
uiFeatureHighlight([
|
|
@@ -35,6 +89,7 @@ exports.handler = async (options) => {
|
|
|
35
89
|
'feedbackCommand',
|
|
36
90
|
'sampleProjects',
|
|
37
91
|
]);
|
|
92
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
38
93
|
};
|
|
39
94
|
exports.builder = yargs => {
|
|
40
95
|
yargs.options({
|
|
@@ -71,9 +71,9 @@ exports.handler = async (options) => {
|
|
|
71
71
|
let projectName;
|
|
72
72
|
let projectDest;
|
|
73
73
|
try {
|
|
74
|
-
const
|
|
75
|
-
projectName =
|
|
76
|
-
projectDest =
|
|
74
|
+
const createProjectPromptResponse = await createProjectPrompt(options);
|
|
75
|
+
projectName = createProjectPromptResponse.name;
|
|
76
|
+
projectDest = createProjectPromptResponse.dest;
|
|
77
77
|
const { projectExists } = await ensureProjectExists(derivedAccountId, projectName, {
|
|
78
78
|
allowCreate: false,
|
|
79
79
|
noLogs: true,
|
|
@@ -20,7 +20,7 @@ const i18nKey = 'commands.project.subcommands.upload';
|
|
|
20
20
|
exports.command = 'upload';
|
|
21
21
|
exports.describe = uiBetaTag(i18n(`${i18nKey}.describe`), false);
|
|
22
22
|
exports.handler = async (options) => {
|
|
23
|
-
const { forceCreate, message, derivedAccountId
|
|
23
|
+
const { forceCreate, message, derivedAccountId } = options;
|
|
24
24
|
const accountConfig = getAccountConfig(derivedAccountId);
|
|
25
25
|
const accountType = accountConfig && accountConfig.accountType;
|
|
26
26
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
@@ -31,7 +31,7 @@ exports.handler = async (options) => {
|
|
|
31
31
|
uploadCommand: true,
|
|
32
32
|
});
|
|
33
33
|
try {
|
|
34
|
-
const { result, uploadError } = await handleProjectUpload(derivedAccountId, projectConfig, projectDir, pollProjectBuildAndDeploy, message, useV3Api(projectConfig?.platformVersion)
|
|
34
|
+
const { result, uploadError } = await handleProjectUpload(derivedAccountId, projectConfig, projectDir, pollProjectBuildAndDeploy, message, useV3Api(projectConfig?.platformVersion));
|
|
35
35
|
if (uploadError) {
|
|
36
36
|
if (isSpecifiedError(uploadError, {
|
|
37
37
|
subCategory: PROJECT_ERROR_TYPES.PROJECT_LOCKED,
|
|
@@ -81,11 +81,6 @@ exports.builder = yargs => {
|
|
|
81
81
|
type: 'string',
|
|
82
82
|
default: '',
|
|
83
83
|
},
|
|
84
|
-
'bypass-validation': {
|
|
85
|
-
type: 'boolean',
|
|
86
|
-
hidden: true,
|
|
87
|
-
default: false,
|
|
88
|
-
},
|
|
89
84
|
});
|
|
90
85
|
yargs.example([['$0 project upload', i18n(`${i18nKey}.examples.default`)]]);
|
|
91
86
|
addConfigOptions(yargs);
|
package/lang/en.lyaml
CHANGED
|
@@ -530,7 +530,12 @@ en:
|
|
|
530
530
|
default: "Start local dev for the current project"
|
|
531
531
|
create:
|
|
532
532
|
describe: "Create a new project."
|
|
533
|
+
errors:
|
|
534
|
+
failedToDownloadProject: "Failed to download project. Please try again later."
|
|
535
|
+
failedToFetchProjectList: "Failed to fetch the list of available project templates. Please try again later."
|
|
536
|
+
cannotNestProjects: "A project already exists at {{ projectDir }}. Projects cannot be nested within other projects. Please choose a different destination and try again."
|
|
533
537
|
logs:
|
|
538
|
+
success: "Project {{#bold}}{{ projectName }}{{/bold}} was successfully created in {{ projectDest }}"
|
|
534
539
|
welcomeMessage: "Welcome to HubSpot Developer Projects!"
|
|
535
540
|
examples:
|
|
536
541
|
default: "Create a new project"
|
|
@@ -603,12 +608,13 @@ en:
|
|
|
603
608
|
describe: "The name for your newly created component"
|
|
604
609
|
type:
|
|
605
610
|
describe: "The path to the component type's location within the hubspot-project-components Github repo: https://github.com/HubSpot/hubspot-project-components"
|
|
606
|
-
creatingComponent:
|
|
607
|
-
|
|
608
|
-
success:
|
|
609
|
-
message: "{{ componentName }} was added to your project"
|
|
611
|
+
creatingComponent: "Adding a new component to {{#bold}}{{ projectName }}{{/bold}}"
|
|
612
|
+
success: "{{ componentName }} was successfully added to your project."
|
|
610
613
|
error:
|
|
611
|
-
|
|
614
|
+
failedToDownloadComponent: "Failed to download project component. Please try again later."
|
|
615
|
+
locationInProject: "This command must be run from within a project directory."
|
|
616
|
+
failedToFetchComponentList: "Failed to fetch the list of available components. Please try again later."
|
|
617
|
+
projectContainsPublicApp: "This project contains a public app. This command is currently only compatible with projects that contain private apps."
|
|
612
618
|
examples:
|
|
613
619
|
default: "Create a component within your project"
|
|
614
620
|
withFlags: "Use --name and --type flags to bypass the prompt."
|
|
@@ -1106,6 +1112,11 @@ en:
|
|
|
1106
1112
|
checkIfParentAccountIsAuthed:
|
|
1107
1113
|
notAuthedError: "To develop this project locally, run {{ authCommand }} to authenticate the App Developer Account {{ accountId }} associated with {{ accountIdentifier }}."
|
|
1108
1114
|
projects:
|
|
1115
|
+
create:
|
|
1116
|
+
errors:
|
|
1117
|
+
noProjectsInConfig: "Unable to find any projects in the target repository's config.json file. Please ensure that there is a \"projects\" array in the config file."
|
|
1118
|
+
missingConfigFileTemplateSource: "Failed to fetch the config.json file from the target repository. Please ensure that there is a valid config.json file at the root of the repository and try again."
|
|
1119
|
+
missingPropertiesInConfig: "Found misconfigured projects in the target repository's config.json file. Please ensure that each project in the target repository's config.json file contains the following properties: [\"name\", \"label\", \"path\", \"insertPath\"]."
|
|
1109
1120
|
validateProjectConfig:
|
|
1110
1121
|
configNotFound: "Unable to locate a project configuration file. Try running again from a project directory, or run {{ createCommand }} to create a new project."
|
|
1111
1122
|
configMissingFields: "The project configuruation file is missing required fields."
|
|
@@ -1313,12 +1324,9 @@ en:
|
|
|
1313
1324
|
errors:
|
|
1314
1325
|
nameRequired: "A project name is required"
|
|
1315
1326
|
destRequired: "A project dest is required"
|
|
1316
|
-
invalidDest: "
|
|
1327
|
+
invalidDest: "There is an existing project at this destination. Please provide a new path for this project."
|
|
1317
1328
|
invalidCharacters: "The selected destination contains invalid characters. Please provide a new path and try again."
|
|
1318
|
-
invalidTemplate: "[--template] Could not find template {{ template }}. Please choose an available template
|
|
1319
|
-
noProjectsInConfig: "Please ensure that there is a config.json file that contains a \"projects\" field."
|
|
1320
|
-
missingConfigFileTemplateSource: "Please ensure that there is a config.json file in the repository used as the --template-source"
|
|
1321
|
-
missingPropertiesInConfig: "Please ensure that each of the projects in your config.json file contain the following properties: [\"name\", \"label\", \"path\", \"insertPath\"]."
|
|
1329
|
+
invalidTemplate: "[--template] Could not find template \"{{ template }}\". Please choose an available template:"
|
|
1322
1330
|
selectPublicAppPrompt:
|
|
1323
1331
|
selectAppIdMigrate: "[--appId] Choose an app under {{ accountName }} to migrate:"
|
|
1324
1332
|
selectAppIdClone: "[--appId] Choose an app under {{ accountName }} to clone:"
|
|
@@ -1336,11 +1344,11 @@ en:
|
|
|
1336
1344
|
projectNotFound: "Your project {{ projectName }} could not be found in {{ accountId }}. Please select a valid project:"
|
|
1337
1345
|
accountIdRequired: "An account ID is required to download a project."
|
|
1338
1346
|
projectAddPrompt:
|
|
1339
|
-
selectType: "[--type] Select
|
|
1347
|
+
selectType: "[--type] Select a component to add: "
|
|
1340
1348
|
enterName: "[--name] Give your component a name: "
|
|
1341
1349
|
errors:
|
|
1342
1350
|
nameRequired: "A component name is required"
|
|
1343
|
-
invalidType: "[--type] Could not find type {{ type }}. Please choose an available type
|
|
1351
|
+
invalidType: "[--type] Could not find type \"{{ type }}\". Please choose an available type:"
|
|
1344
1352
|
secretPrompt:
|
|
1345
1353
|
enterValue: "Enter a value for your secret: "
|
|
1346
1354
|
enterName: "Enter a name for your secret: "
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { RepoPath } from '@hubspot/local-dev-lib/types/Github';
|
|
2
|
+
import { ProjectTemplate, ComponentTemplate } from '../../types/Projects';
|
|
3
|
+
export declare const EMPTY_PROJECT_TEMPLATE_NAME = "no-template";
|
|
4
|
+
export declare function getProjectComponentListFromRepo(githubRef: string): Promise<ComponentTemplate[]>;
|
|
5
|
+
export declare function getProjectTemplateListFromRepo(templateSource: RepoPath, githubRef: string): Promise<ProjectTemplate[]>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EMPTY_PROJECT_TEMPLATE_NAME = void 0;
|
|
4
|
+
exports.getProjectComponentListFromRepo = getProjectComponentListFromRepo;
|
|
5
|
+
exports.getProjectTemplateListFromRepo = getProjectTemplateListFromRepo;
|
|
6
|
+
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
7
|
+
const github_1 = require("@hubspot/local-dev-lib/api/github");
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
const exitCodes_1 = require("../enums/exitCodes");
|
|
10
|
+
const lang_1 = require("../lang");
|
|
11
|
+
const index_1 = require("../errorHandlers/index");
|
|
12
|
+
const i18nKey = 'lib.projects.create';
|
|
13
|
+
exports.EMPTY_PROJECT_TEMPLATE_NAME = 'no-template';
|
|
14
|
+
const PROJECT_TEMPLATE_PROPERTIES = ['name', 'label', 'path', 'insertPath'];
|
|
15
|
+
async function getProjectComponentListFromRepo(githubRef) {
|
|
16
|
+
let config;
|
|
17
|
+
try {
|
|
18
|
+
const { data } = await (0, github_1.fetchRepoFile)(constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, 'config.json', githubRef);
|
|
19
|
+
config = data;
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
(0, index_1.debugError)(err);
|
|
23
|
+
}
|
|
24
|
+
if (config) {
|
|
25
|
+
return config[constants_1.PROJECT_COMPONENT_TYPES.COMPONENTS] || [];
|
|
26
|
+
}
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
async function getProjectTemplateListFromRepo(templateSource, githubRef) {
|
|
30
|
+
let config;
|
|
31
|
+
try {
|
|
32
|
+
const { data } = await (0, github_1.fetchRepoFile)(templateSource, 'config.json', githubRef);
|
|
33
|
+
config = data;
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
(0, index_1.debugError)(e);
|
|
37
|
+
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.missingConfigFileTemplateSource`));
|
|
38
|
+
return process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
39
|
+
}
|
|
40
|
+
if (!config || !config[constants_1.PROJECT_COMPONENT_TYPES.PROJECTS]) {
|
|
41
|
+
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.noProjectsInConfig`));
|
|
42
|
+
return process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
43
|
+
}
|
|
44
|
+
const templates = config[constants_1.PROJECT_COMPONENT_TYPES.PROJECTS];
|
|
45
|
+
const templatesContainAllProperties = templates.every(config => PROJECT_TEMPLATE_PROPERTIES.every(p => Object.prototype.hasOwnProperty.call(config, p)));
|
|
46
|
+
if (!templatesContainAllProperties) {
|
|
47
|
+
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.missingPropertiesInConfig`));
|
|
48
|
+
return process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
49
|
+
}
|
|
50
|
+
return templates;
|
|
51
|
+
}
|
package/lib/projects/index.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import { RepoPath } from '@hubspot/local-dev-lib/types/Github';
|
|
2
1
|
import { Project } from '@hubspot/local-dev-lib/types/Project';
|
|
3
|
-
import {
|
|
2
|
+
import { ProjectConfig } from '../../types/Projects';
|
|
4
3
|
export declare function writeProjectConfig(configPath: string, config: ProjectConfig): boolean;
|
|
5
4
|
export declare function getIsInProject(dir?: string): boolean;
|
|
6
5
|
export declare function getProjectConfig(dir?: string): Promise<{
|
|
7
6
|
projectDir: string | null;
|
|
8
7
|
projectConfig: ProjectConfig | null;
|
|
9
8
|
}>;
|
|
10
|
-
export declare function createProjectConfig(projectPath: string, projectName: string, template: ProjectTemplate, templateSource: RepoPath, githubRef: string): Promise<boolean>;
|
|
11
9
|
export declare function validateProjectConfig(projectConfig: ProjectConfig, projectDir: string): void;
|
|
12
10
|
export declare function ensureProjectExists(accountId: number, projectName: string, { forceCreate, allowCreate, noLogs, withPolling, uploadCommand, }?: {
|
|
13
11
|
forceCreate?: boolean | undefined;
|
|
@@ -20,5 +18,3 @@ export declare function ensureProjectExists(accountId: number, projectName: stri
|
|
|
20
18
|
project?: Project;
|
|
21
19
|
}>;
|
|
22
20
|
export declare function logFeedbackMessage(buildId: number): void;
|
|
23
|
-
export declare function createProjectComponent(component: ProjectAddComponentData, name: string, projectComponentsVersion: string): Promise<void>;
|
|
24
|
-
export declare function getProjectComponentsByVersion(projectComponentsVersion: string): Promise<ComponentTemplate[]>;
|
package/lib/projects/index.js
CHANGED
|
@@ -6,17 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.writeProjectConfig = writeProjectConfig;
|
|
7
7
|
exports.getIsInProject = getIsInProject;
|
|
8
8
|
exports.getProjectConfig = getProjectConfig;
|
|
9
|
-
exports.createProjectConfig = createProjectConfig;
|
|
10
9
|
exports.validateProjectConfig = validateProjectConfig;
|
|
11
10
|
exports.ensureProjectExists = ensureProjectExists;
|
|
12
11
|
exports.logFeedbackMessage = logFeedbackMessage;
|
|
13
|
-
exports.createProjectComponent = createProjectComponent;
|
|
14
|
-
exports.getProjectComponentsByVersion = getProjectComponentsByVersion;
|
|
15
12
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
16
13
|
const path_1 = __importDefault(require("path"));
|
|
17
14
|
const findup_sync_1 = __importDefault(require("findup-sync"));
|
|
18
15
|
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
19
|
-
const github_1 = require("@hubspot/local-dev-lib/github");
|
|
20
16
|
const projects_1 = require("@hubspot/local-dev-lib/api/projects");
|
|
21
17
|
const index_1 = require("@hubspot/local-dev-lib/errors/index");
|
|
22
18
|
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
@@ -53,7 +49,7 @@ function getProjectConfigPath(dir) {
|
|
|
53
49
|
return configPath;
|
|
54
50
|
}
|
|
55
51
|
async function getProjectConfig(dir) {
|
|
56
|
-
const configPath =
|
|
52
|
+
const configPath = getProjectConfigPath(dir);
|
|
57
53
|
if (!configPath) {
|
|
58
54
|
return { projectConfig: null, projectDir: null };
|
|
59
55
|
}
|
|
@@ -70,45 +66,6 @@ async function getProjectConfig(dir) {
|
|
|
70
66
|
return { projectConfig: null, projectDir: null };
|
|
71
67
|
}
|
|
72
68
|
}
|
|
73
|
-
async function createProjectConfig(projectPath, projectName, template, templateSource, githubRef) {
|
|
74
|
-
const { projectConfig, projectDir } = await getProjectConfig(projectPath);
|
|
75
|
-
if (projectConfig) {
|
|
76
|
-
logger_1.logger.warn(projectPath === projectDir
|
|
77
|
-
? 'A project already exists in that location.'
|
|
78
|
-
: `Found an existing project definition in ${projectDir}.`);
|
|
79
|
-
const { shouldContinue } = await (0, promptUtils_1.promptUser)([
|
|
80
|
-
{
|
|
81
|
-
name: 'shouldContinue',
|
|
82
|
-
message: () => {
|
|
83
|
-
return projectPath === projectDir
|
|
84
|
-
? 'Do you want to overwrite the existing project definition with a new one?'
|
|
85
|
-
: `Continue creating a new project in ${projectPath}?`;
|
|
86
|
-
},
|
|
87
|
-
type: 'confirm',
|
|
88
|
-
default: false,
|
|
89
|
-
},
|
|
90
|
-
]);
|
|
91
|
-
if (!shouldContinue) {
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
const projectConfigPath = path_1.default.join(projectPath, constants_1.PROJECT_CONFIG_FILE);
|
|
96
|
-
logger_1.logger.log(`Creating project config in ${projectPath ? projectPath : 'the current folder'}`);
|
|
97
|
-
const hasCustomTemplateSource = Boolean(templateSource);
|
|
98
|
-
await (0, github_1.cloneGithubRepo)(templateSource || constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, projectPath, {
|
|
99
|
-
sourceDir: template.path,
|
|
100
|
-
tag: hasCustomTemplateSource ? undefined : githubRef,
|
|
101
|
-
});
|
|
102
|
-
const _config = JSON.parse(fs_extra_1.default.readFileSync(projectConfigPath).toString());
|
|
103
|
-
writeProjectConfig(projectConfigPath, {
|
|
104
|
-
..._config,
|
|
105
|
-
name: projectName,
|
|
106
|
-
});
|
|
107
|
-
if (template.name === 'no-template') {
|
|
108
|
-
fs_extra_1.default.ensureDirSync(path_1.default.join(projectPath, 'src'));
|
|
109
|
-
}
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
69
|
function validateProjectConfig(projectConfig, projectDir) {
|
|
113
70
|
if (!projectConfig) {
|
|
114
71
|
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.validateProjectConfig.configNotFound`, {
|
|
@@ -235,21 +192,3 @@ function logFeedbackMessage(buildId) {
|
|
|
235
192
|
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.logFeedbackMessage.feedbackMessage`));
|
|
236
193
|
}
|
|
237
194
|
}
|
|
238
|
-
async function createProjectComponent(component, name, projectComponentsVersion) {
|
|
239
|
-
const i18nKey = 'commands.project.subcommands.add';
|
|
240
|
-
const componentName = name;
|
|
241
|
-
const configInfo = await getProjectConfig();
|
|
242
|
-
if (!configInfo.projectDir || !configInfo.projectConfig) {
|
|
243
|
-
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.error.locationInProject`));
|
|
244
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
245
|
-
}
|
|
246
|
-
const componentPath = path_1.default.join(configInfo.projectDir, configInfo.projectConfig.srcDir, component.insertPath, componentName);
|
|
247
|
-
await (0, github_1.cloneGithubRepo)(constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, componentPath, {
|
|
248
|
-
sourceDir: component.path,
|
|
249
|
-
tag: projectComponentsVersion,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
async function getProjectComponentsByVersion(projectComponentsVersion) {
|
|
253
|
-
const config = await (0, github_1.fetchFileFromRepository)(constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, 'config.json', projectComponentsVersion);
|
|
254
|
-
return config[constants_1.PROJECT_COMPONENT_TYPES.COMPONENTS] || [];
|
|
255
|
-
}
|
package/lib/projects/upload.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ type ProjectUploadResult<T> = {
|
|
|
5
5
|
result?: T;
|
|
6
6
|
uploadError?: unknown;
|
|
7
7
|
};
|
|
8
|
-
export declare function handleProjectUpload<T>(accountId: number, projectConfig: ProjectConfig, projectDir: string, callbackFunc: ProjectUploadCallbackFunction<T>, uploadMessage: string, sendIR?: boolean
|
|
8
|
+
export declare function handleProjectUpload<T>(accountId: number, projectConfig: ProjectConfig, projectDir: string, callbackFunc: ProjectUploadCallbackFunction<T>, uploadMessage: string, sendIR?: boolean): Promise<ProjectUploadResult<T>>;
|
|
9
9
|
export {};
|
package/lib/projects/upload.js
CHANGED
|
@@ -58,7 +58,7 @@ async function uploadProjectFiles(accountId, projectName, filePath, uploadMessag
|
|
|
58
58
|
}
|
|
59
59
|
return { buildId, error };
|
|
60
60
|
}
|
|
61
|
-
async function handleProjectUpload(accountId, projectConfig, projectDir, callbackFunc, uploadMessage, sendIR = false
|
|
61
|
+
async function handleProjectUpload(accountId, projectConfig, projectDir, callbackFunc, uploadMessage, sendIR = false) {
|
|
62
62
|
const srcDir = path_1.default.resolve(projectDir, projectConfig.srcDir);
|
|
63
63
|
const filenames = fs_extra_1.default.readdirSync(srcDir);
|
|
64
64
|
if (!filenames || filenames.length === 0) {
|
|
@@ -84,7 +84,7 @@ async function handleProjectUpload(accountId, projectConfig, projectDir, callbac
|
|
|
84
84
|
projectSourceDir: path_1.default.join(projectDir, projectConfig.srcDir),
|
|
85
85
|
platformVersion: projectConfig.platformVersion,
|
|
86
86
|
accountId,
|
|
87
|
-
}
|
|
87
|
+
});
|
|
88
88
|
logger_1.logger.debug(node_util_1.default.inspect(intermediateRepresentation, false, null, true));
|
|
89
89
|
}
|
|
90
90
|
catch (e) {
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { RepoPath } from '@hubspot/local-dev-lib/types/Github';
|
|
2
1
|
import { ProjectTemplate } from '../../types/Projects';
|
|
3
2
|
type CreateProjectPromptResponse = {
|
|
4
3
|
name: string;
|
|
5
4
|
dest: string;
|
|
6
|
-
|
|
5
|
+
projectTemplate?: ProjectTemplate;
|
|
7
6
|
};
|
|
8
|
-
export declare function createProjectPrompt(
|
|
9
|
-
name
|
|
10
|
-
dest
|
|
11
|
-
template
|
|
12
|
-
|
|
13
|
-
}, skipTemplatePrompt?: boolean): Promise<CreateProjectPromptResponse>;
|
|
7
|
+
export declare function createProjectPrompt(promptOptions: {
|
|
8
|
+
name?: string;
|
|
9
|
+
dest?: string;
|
|
10
|
+
template?: string;
|
|
11
|
+
}, projectTemplates?: ProjectTemplate[]): Promise<CreateProjectPromptResponse>;
|
|
14
12
|
export {};
|
|
@@ -7,52 +7,17 @@ exports.createProjectPrompt = createProjectPrompt;
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
10
|
-
const github_1 = require("@hubspot/local-dev-lib/github");
|
|
11
|
-
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
12
|
-
const constants_1 = require("../constants");
|
|
13
10
|
const promptUtils_1 = require("./promptUtils");
|
|
14
11
|
const lang_1 = require("../lang");
|
|
15
|
-
const exitCodes_1 = require("../enums/exitCodes");
|
|
16
12
|
const i18nKey = 'lib.prompts.createProjectPrompt';
|
|
17
|
-
|
|
18
|
-
function hasAllProperties(projectList) {
|
|
19
|
-
return projectList.every(config => PROJECT_TEMPLATE_PROPERTIES.every(p => Object.prototype.hasOwnProperty.call(config, p)));
|
|
20
|
-
}
|
|
21
|
-
async function createTemplateOptions(templateSource, githubRef) {
|
|
22
|
-
const hasCustomTemplateSource = Boolean(templateSource);
|
|
23
|
-
const branch = hasCustomTemplateSource
|
|
24
|
-
? constants_1.DEFAULT_PROJECT_TEMPLATE_BRANCH
|
|
25
|
-
: githubRef;
|
|
26
|
-
let config;
|
|
27
|
-
try {
|
|
28
|
-
config = await (0, github_1.fetchFileFromRepository)(templateSource || constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, 'config.json', branch);
|
|
29
|
-
}
|
|
30
|
-
catch (e) {
|
|
31
|
-
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.missingConfigFileTemplateSource`));
|
|
32
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
33
|
-
}
|
|
34
|
-
if (!config || !config[constants_1.PROJECT_COMPONENT_TYPES.PROJECTS]) {
|
|
35
|
-
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.noProjectsInConfig`));
|
|
36
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
37
|
-
}
|
|
38
|
-
if (!hasAllProperties(config[constants_1.PROJECT_COMPONENT_TYPES.PROJECTS])) {
|
|
39
|
-
logger_1.logger.error((0, lang_1.i18n)(`${i18nKey}.errors.missingPropertiesInConfig`));
|
|
40
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
41
|
-
}
|
|
42
|
-
return config[constants_1.PROJECT_COMPONENT_TYPES.PROJECTS];
|
|
43
|
-
}
|
|
44
|
-
function findTemplate(projectTemplates, templateNameOrLabel) {
|
|
13
|
+
function findTemplateByNameOrLabel(projectTemplates, templateNameOrLabel) {
|
|
45
14
|
return projectTemplates.find(t => t.name === templateNameOrLabel || t.label === templateNameOrLabel);
|
|
46
15
|
}
|
|
47
|
-
async function createProjectPrompt(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
projectTemplates
|
|
52
|
-
selectedTemplate =
|
|
53
|
-
promptOptions.template &&
|
|
54
|
-
findTemplate(projectTemplates, promptOptions.template);
|
|
55
|
-
}
|
|
16
|
+
async function createProjectPrompt(promptOptions, projectTemplates) {
|
|
17
|
+
const createProjectFromTemplate = !!projectTemplates && projectTemplates.length > 0;
|
|
18
|
+
const providedTemplateIsValid = createProjectFromTemplate &&
|
|
19
|
+
!!promptOptions.template &&
|
|
20
|
+
!!findTemplateByNameOrLabel(projectTemplates, promptOptions.template);
|
|
56
21
|
const result = await (0, promptUtils_1.promptUser)([
|
|
57
22
|
{
|
|
58
23
|
name: 'name',
|
|
@@ -70,7 +35,7 @@ async function createProjectPrompt(githubRef, promptOptions, skipTemplatePrompt
|
|
|
70
35
|
message: (0, lang_1.i18n)(`${i18nKey}.enterDest`),
|
|
71
36
|
when: !promptOptions.dest,
|
|
72
37
|
default: answers => {
|
|
73
|
-
const projectName = (0, path_2.sanitizeFileName)(
|
|
38
|
+
const projectName = (0, path_2.sanitizeFileName)(promptOptions.name || answers.name);
|
|
74
39
|
return path_1.default.resolve((0, path_2.getCwd)(), projectName);
|
|
75
40
|
},
|
|
76
41
|
validate: (input) => {
|
|
@@ -90,27 +55,34 @@ async function createProjectPrompt(githubRef, promptOptions, skipTemplatePrompt
|
|
|
90
55
|
},
|
|
91
56
|
},
|
|
92
57
|
{
|
|
93
|
-
name: '
|
|
58
|
+
name: 'projectTemplate',
|
|
94
59
|
message: () => {
|
|
95
|
-
return promptOptions.template &&
|
|
96
|
-
!findTemplate(projectTemplates, promptOptions.template)
|
|
60
|
+
return promptOptions.template && !providedTemplateIsValid
|
|
97
61
|
? (0, lang_1.i18n)(`${i18nKey}.errors.invalidTemplate`, {
|
|
98
62
|
template: promptOptions.template,
|
|
99
63
|
})
|
|
100
64
|
: (0, lang_1.i18n)(`${i18nKey}.selectTemplate`);
|
|
101
65
|
},
|
|
102
|
-
when:
|
|
66
|
+
when: createProjectFromTemplate && !providedTemplateIsValid,
|
|
103
67
|
type: 'list',
|
|
104
|
-
choices:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
68
|
+
choices: createProjectFromTemplate
|
|
69
|
+
? projectTemplates.map(template => {
|
|
70
|
+
return {
|
|
71
|
+
name: template.label,
|
|
72
|
+
value: template,
|
|
73
|
+
};
|
|
74
|
+
})
|
|
75
|
+
: undefined,
|
|
110
76
|
},
|
|
111
77
|
]);
|
|
112
|
-
if (
|
|
113
|
-
result.
|
|
78
|
+
if (!result.name) {
|
|
79
|
+
result.name = promptOptions.name;
|
|
80
|
+
}
|
|
81
|
+
if (!result.dest) {
|
|
82
|
+
result.dest = promptOptions.dest;
|
|
83
|
+
}
|
|
84
|
+
if (providedTemplateIsValid) {
|
|
85
|
+
result.projectTemplate = findTemplateByNameOrLabel(projectTemplates, promptOptions.template);
|
|
114
86
|
}
|
|
115
87
|
return result;
|
|
116
88
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComponentTemplate } from '../../types/Projects';
|
|
2
2
|
type ProjectAddPromptResponse = {
|
|
3
|
-
|
|
3
|
+
componentTemplate: ComponentTemplate;
|
|
4
4
|
name: string;
|
|
5
5
|
};
|
|
6
|
-
export declare function projectAddPrompt(components:
|
|
6
|
+
export declare function projectAddPrompt(components: ComponentTemplate[], promptOptions?: {
|
|
7
7
|
name?: string;
|
|
8
8
|
type?: string;
|
|
9
9
|
}): Promise<ProjectAddPromptResponse>;
|
|
@@ -4,20 +4,23 @@ exports.projectAddPrompt = projectAddPrompt;
|
|
|
4
4
|
const promptUtils_1 = require("./promptUtils");
|
|
5
5
|
const lang_1 = require("../lang");
|
|
6
6
|
const i18nKey = 'lib.prompts.projectAddPrompt';
|
|
7
|
+
function findComponentByPathOrLabel(components, componentPathOrLabel) {
|
|
8
|
+
return components.find(c => c.path === componentPathOrLabel || c.label === componentPathOrLabel);
|
|
9
|
+
}
|
|
7
10
|
async function projectAddPrompt(components, promptOptions = {}) {
|
|
8
|
-
|
|
11
|
+
const providedTypeIsValid = !!promptOptions.type &&
|
|
12
|
+
!!findComponentByPathOrLabel(components, promptOptions.type);
|
|
13
|
+
const result = await (0, promptUtils_1.promptUser)([
|
|
9
14
|
{
|
|
10
|
-
name: '
|
|
15
|
+
name: 'componentTemplate',
|
|
11
16
|
message: () => {
|
|
12
|
-
return promptOptions.type &&
|
|
13
|
-
!components.find(t => t.path === promptOptions.type)
|
|
17
|
+
return promptOptions.type && !providedTypeIsValid
|
|
14
18
|
? (0, lang_1.i18n)(`${i18nKey}.errors.invalidType`, {
|
|
15
19
|
type: promptOptions.type,
|
|
16
20
|
})
|
|
17
21
|
: (0, lang_1.i18n)(`${i18nKey}.selectType`);
|
|
18
22
|
},
|
|
19
|
-
when: !
|
|
20
|
-
!components.find(t => t.path === promptOptions.type),
|
|
23
|
+
when: !providedTypeIsValid,
|
|
21
24
|
type: 'list',
|
|
22
25
|
choices: components.map(type => {
|
|
23
26
|
return {
|
|
@@ -38,4 +41,11 @@ async function projectAddPrompt(components, promptOptions = {}) {
|
|
|
38
41
|
},
|
|
39
42
|
},
|
|
40
43
|
]);
|
|
44
|
+
if (!result.name) {
|
|
45
|
+
result.name = promptOptions.name;
|
|
46
|
+
}
|
|
47
|
+
if (providedTypeIsValid) {
|
|
48
|
+
result.componentTemplate = findComponentByPathOrLabel(components, promptOptions.type);
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
41
51
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.16-experimental.0",
|
|
4
4
|
"description": "The official CLI for developing on HubSpot",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": "https://github.com/HubSpot/hubspot-cli",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@hubspot/local-dev-lib": "3.3.1",
|
|
9
|
-
"@hubspot/project-parsing-lib": "0.0.6-
|
|
9
|
+
"@hubspot/project-parsing-lib": "0.0.6-experimental.0",
|
|
10
10
|
"@hubspot/serverless-dev-runtime": "7.0.2",
|
|
11
11
|
"@hubspot/theme-preview-dev-server": "0.0.10",
|
|
12
12
|
"@hubspot/ui-extensions-dev-server": "0.8.42",
|
package/types/Projects.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ export type ProjectTemplate = {
|
|
|
7
7
|
insertPath: string;
|
|
8
8
|
};
|
|
9
9
|
export type ComponentTemplate = {
|
|
10
|
-
label: string;
|
|
11
10
|
path: string;
|
|
11
|
+
label: string;
|
|
12
12
|
insertPath: string;
|
|
13
13
|
};
|
|
14
14
|
export type ProjectConfig = {
|
|
@@ -32,11 +32,6 @@ export type ProjectPollStatusFunctionText = {
|
|
|
32
32
|
TYPE_KEY: string;
|
|
33
33
|
SUBTASK_NAME_KEY: string;
|
|
34
34
|
};
|
|
35
|
-
export type ProjectAddComponentData = {
|
|
36
|
-
path: string;
|
|
37
|
-
label: string;
|
|
38
|
-
insertPath: string;
|
|
39
|
-
};
|
|
40
35
|
export type ProjectTemplateRepoConfig = {
|
|
41
36
|
projects?: ProjectTemplate[];
|
|
42
37
|
components?: ComponentTemplate[];
|