@forge/cli
11.2.1-next.2-experimental-611b36611.3.0-next.4-experimental-011b3b2
out/command-line/register-app-commands.jsout/command-line/register-app-commands.js+101−54
Index: package/out/command-line/register-app-commands.js
===================================================================
--- package/out/command-line/register-app-commands.js
+++ package/out/command-line/register-app-commands.js
@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-exports.registerCommands = exports.createCommandHandler = exports.directoryNameFromAppName = exports.templateMatchesProduct = exports.formatProduct = void 0;
+exports.registerCommands = exports.createCommandHandler = exports.directoryNameFromAppName = exports.templateMatchesProduct = exports.formatProduct = exports.CATEGORY_PREDICATES = exports.PRODUCT_OPTIONS_DISPLAY = exports.TemplateContext = exports.TemplateCategory = void 0;
const tslib_1 = require("tslib");
const fs_1 = tslib_1.__importDefault(require("fs"));
const sanitize_filename_1 = tslib_1.__importDefault(require("sanitize-filename"));
const cli_shared_1 = require("@forge/cli-shared");
@@ -11,24 +11,57 @@
TemplateCategory["ROVO"] = "Rovo Agent and action";
TemplateCategory["UI_KIT_2"] = "UI Kit";
TemplateCategory["CUSTOM_UI"] = "Custom UI";
TemplateCategory["BACKEND"] = "Triggers and Validators";
-})(TemplateCategory || (TemplateCategory = {}));
-const PRODUCT_OPTIONS = [
- 'show-all',
- 'bitbucket',
- 'compass',
- 'confluence',
- 'jira',
- 'jira-service-management',
- 'teamwork-graph'
+})(TemplateCategory = exports.TemplateCategory || (exports.TemplateCategory = {}));
+var TemplateContext;
+(function (TemplateContext) {
+ TemplateContext["SHOW_ALL"] = "show-all";
+ TemplateContext["BITBUCKET"] = "bitbucket";
+ TemplateContext["COMPASS"] = "compass";
+ TemplateContext["CONFLUENCE"] = "confluence";
+ TemplateContext["JIRA"] = "jira";
+ TemplateContext["JIRA_SERVICE_MANAGEMENT"] = "jira-service-management";
+ TemplateContext["TEAMWORK_GRAPH"] = "teamwork-graph";
+ TemplateContext["ROVO"] = "rovo";
+ TemplateContext["CROSS_CONTEXT"] = "cross-context";
+})(TemplateContext = exports.TemplateContext || (exports.TemplateContext = {}));
+const PRODUCT_OPTIONS = {
+ [TemplateContext.SHOW_ALL]: [TemplateContext.SHOW_ALL],
+ [TemplateContext.BITBUCKET]: [TemplateContext.BITBUCKET],
+ [TemplateContext.COMPASS]: [TemplateContext.COMPASS],
+ [TemplateContext.CONFLUENCE]: [TemplateContext.CONFLUENCE],
+ [TemplateContext.JIRA]: [TemplateContext.JIRA],
+ [TemplateContext.JIRA_SERVICE_MANAGEMENT]: [TemplateContext.JIRA_SERVICE_MANAGEMENT],
+ [TemplateContext.TEAMWORK_GRAPH]: [TemplateContext.TEAMWORK_GRAPH],
+ [TemplateContext.ROVO]: [TemplateContext.ROVO],
+ [TemplateContext.CROSS_CONTEXT]: [
+ TemplateContext.COMPASS,
+ TemplateContext.CONFLUENCE,
+ TemplateContext.JIRA,
+ TemplateContext.JIRA_SERVICE_MANAGEMENT
+ ]
+};
+exports.PRODUCT_OPTIONS_DISPLAY = {
+ [TemplateContext.CROSS_CONTEXT]: 'Cross-context'
+};
+exports.CATEGORY_PREDICATES = [
+ [TemplateCategory.SHOW_ALL, (name) => !!name],
+ [TemplateCategory.ROVO, (name) => name.includes('rovo')],
+ [TemplateCategory.UI_KIT_2, (name) => name.includes('ui-kit')],
+ [TemplateCategory.CUSTOM_UI, (name) => name.includes('custom-ui')],
+ [
+ TemplateCategory.BACKEND,
+ (name) => !!name && !name.includes('ui-kit') && !name.includes('custom-ui') && !name.includes('rovo') && name !== 'blank'
+ ]
];
const MAX_NAME_LENGTH = 60;
function formatProduct(product) {
- return product
- .split('-')
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
- .join(' ');
+ return (exports.PRODUCT_OPTIONS_DISPLAY[product] ??
+ product
+ .split('-')
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
+ .join(' '));
}
exports.formatProduct = formatProduct;
function ensureDirectoryDoesntExist(directory) {
if (fs_1.default.existsSync(directory)) {
@@ -39,27 +72,30 @@
if (name.length <= 0 || name.length > MAX_NAME_LENGTH) {
throw new cli_shared_1.ValidationError(cli_shared_1.Text.create.error.name.tooLong(MAX_NAME_LENGTH));
}
}
-async function selectedTemplate(filteredTemplates, type, ui) {
- if (type === TemplateCategory.SHOW_ALL) {
- return await ui.promptForList(cli_shared_1.Text.create.promptTemplate, filteredTemplates);
+async function selectedTemplate(filteredTemplates, ui, categoryPredicates = exports.CATEGORY_PREDICATES) {
+ const categoryMap = filteredTemplates.reduce((map, template) => {
+ for (const [category, matchesCategory] of categoryPredicates) {
+ if (matchesCategory(template)) {
+ const templates = map.get(category) ?? [];
+ templates.push(template);
+ map.set(category, templates);
+ }
+ }
+ return map;
+ }, new Map());
+ if (categoryMap.size) {
+ const sortedCategories = categoryPredicates
+ .filter(([category]) => categoryMap.has(category))
+ .map(([category]) => category);
+ const category = await ui.promptForList(cli_shared_1.Text.create.promptCategory, sortedCategories);
+ const categoryFilteredTemplates = filterTemplatesByCategory(categoryMap.get(category) ?? filteredTemplates, category);
+ const template = await ui.promptForList(cli_shared_1.Text.create.promptTemplate, categoryFilteredTemplates);
+ return modifyTemplateByCategory(template, category);
}
else {
- const productList = PRODUCT_OPTIONS.filter((productName) => productName === 'show-all' ||
- filteredTemplates.some((template) => templateMatchesProduct(productName, template, PRODUCT_OPTIONS)));
- if (productList.length > 1) {
- const product = await ui.promptForList(cli_shared_1.Text.create.promptProduct, productList, {
- format: formatProduct
- });
- const productFilteredTemplates = product === 'show-all'
- ? filteredTemplates
- : filteredTemplates.filter((template) => templateMatchesProduct(product, template, PRODUCT_OPTIONS));
- return await ui.promptForList(cli_shared_1.Text.create.promptTemplate, productFilteredTemplates);
- }
- else {
- return await ui.promptForList(cli_shared_1.Text.create.promptTemplate, filteredTemplates);
- }
+ return await ui.promptForList(cli_shared_1.Text.create.promptTemplate, filteredTemplates);
}
}
function templateMatchesProduct(productName, templateName, products) {
return (templateName.includes(productName) &&
@@ -80,12 +116,18 @@
async function createCommandHandler(ui, createAppCommand, name, { template, directory }) {
directory = prepareDirectoryForApp(ui, name, template, directory);
ui.info(cli_shared_1.Text.ctrlC);
({ name, directory } = await promptAndValidateAppName(ui, name, directory, template));
- template = await promptAndSelectTemplate(ui, createAppCommand, template, directory);
+ const selection = await promptAndSelectTemplate(ui, createAppCommand, template, directory);
+ template = selection.template;
ui.emptyLine();
directory = directory;
- const args = { name, template, directory };
+ const args = {
+ name,
+ template,
+ directory,
+ ...(selection.requiredContext && { requiredProduct: selection.requiredContext })
+ };
const result = await ui.displayProgress(() => createAppCommand.execute(args), cli_shared_1.Text.create.cmd.start, cli_shared_1.Text.create.cmd.success(name));
ui.info(cli_shared_1.Text.create.cmd.successDetails(directory, result.environments));
return result;
}
@@ -123,38 +165,43 @@
if (!template) {
ui.info(cli_shared_1.Text.create.overviewTemplates);
const templates = await ui.displayTemporaryMessage(() => createAppCommand.getAvailableTemplates(), cli_shared_1.Text.create.waitTemplates);
const templatesWithoutCsuik = templates.filter((template) => !template.includes('csuik'));
- const type = await ui.promptForList(cli_shared_1.Text.create.promptCategory, Object.values(TemplateCategory));
- const filteredTemplates = filterTemplatesByCategory(templatesWithoutCsuik, type);
- template = await selectedTemplate(filteredTemplates, type, ui);
- template = modifyTemplateByCategory(template, type);
+ const productOptions = await createAppCommand.filterAvailableProducts(Object.values(TemplateContext), TemplateContext.TEAMWORK_GRAPH, TemplateContext.CROSS_CONTEXT);
+ const productName = await ui.promptForList(cli_shared_1.Text.create.promptProduct, productOptions, {
+ format: formatProduct
+ });
+ const filteredTemplates = (PRODUCT_OPTIONS[productName] ?? [productName])
+ .map((p) => filterTemplatesByProduct(templatesWithoutCsuik, p, productOptions))
+ .flat();
+ const uniqueTemplates = [...new Set(filteredTemplates.length ? filteredTemplates : templatesWithoutCsuik)];
+ template = await selectedTemplate(uniqueTemplates, ui);
if (!directory) {
directory = template;
ensureDirectoryDoesntExist(directory);
}
+ let requiredContext = undefined;
+ if (productName === TemplateContext.CROSS_CONTEXT) {
+ requiredContext = productOptions.find((context) => templateMatchesProduct(context, template, productOptions));
+ }
+ return {
+ template,
+ requiredContext: requiredContext === TemplateContext.JIRA_SERVICE_MANAGEMENT ? TemplateContext.JIRA : requiredContext
+ };
}
- return template;
+ return {
+ template
+ };
}
+function filterTemplatesByProduct(templates, product, productOptions) {
+ return product === 'show-all'
+ ? templates
+ : templates.filter((template) => templateMatchesProduct(product, template, productOptions));
+}
function filterTemplatesByCategory(templates, category) {
return category === TemplateCategory.SHOW_ALL
? templates
- : templates
- .filter((name) => {
- switch (category) {
- case TemplateCategory.BACKEND:
- return (!name.includes('ui-kit') && !name.includes('custom-ui') && !name.includes('rovo') && name !== 'blank');
- case TemplateCategory.CUSTOM_UI:
- return name.includes('custom-ui');
- case TemplateCategory.UI_KIT_2:
- return name.includes('ui-kit');
- case TemplateCategory.ROVO:
- return name.includes('rovo');
- default:
- return true;
- }
- })
- .map((name) => name.replace('-ui-kit', '').replace('-custom-ui', '').replace('-rovo', ''));
+ : templates.map((name) => name.replace('-ui-kit', '').replace('-custom-ui', '').replace('-rovo', ''));
}
function modifyTemplateByCategory(template, category) {
switch (category) {
case TemplateCategory.UI_KIT_2: