@re-shell/cli
Version:
Full-stack development platform uniting microservices and microfrontends. Build complete applications with .NET (ASP.NET Core Web API, Minimal API), Java (Spring Boot, Quarkus, Micronaut, Vert.x), Rust (Actix-Web, Warp, Rocket, Axum), Python (FastAPI, Dja
371 lines (370 loc) ⢠15.3 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BackendTemplateSelector = void 0;
exports.selectBackendTemplate = selectBackendTemplate;
exports.getBackendTemplate = getBackendTemplate;
exports.listBackendTemplates = listBackendTemplates;
const inquirer = __importStar(require("inquirer"));
const chalk_1 = __importDefault(require("chalk"));
const backend_1 = require("../templates/backend");
class BackendTemplateSelector {
constructor() {
this.categories = this.categorizeTemplates();
}
categorizeTemplates() {
const categories = [
{
name: 'Node.js/TypeScript',
value: 'nodejs',
description: 'JavaScript/TypeScript frameworks for Node.js',
icon: 'šØ',
templates: []
},
{
name: 'Python',
value: 'python',
description: 'Python web frameworks and APIs',
icon: 'š',
templates: []
},
{
name: 'Go',
value: 'go',
description: 'High-performance Go frameworks',
icon: 'š¹',
templates: []
},
{
name: 'Kotlin',
value: 'kotlin',
description: 'Kotlin JVM frameworks',
icon: 'šļø',
templates: []
}
];
// Categorize templates by language
Object.values(backend_1.backendTemplates).forEach(template => {
if (template.language === 'typescript' || template.language === 'javascript') {
categories[0].templates.push(template);
}
else if (template.language === 'python') {
categories[1].templates.push(template);
}
else if (template.language === 'go') {
categories[2].templates.push(template);
}
else if (template.language === 'kotlin') {
categories[3].templates.push(template);
}
});
// Sort templates within each category by popularity/recommendation
categories.forEach(category => {
category.templates.sort((a, b) => {
// Prioritize certain frameworks
const priority = {
'express': 1,
'nestjs': 2,
'fastify': 3,
'fastapi': 1,
'django': 2,
'flask': 3,
'gin': 1,
'fiber': 2
};
const aPriority = priority[a.id] || 99;
const bPriority = priority[b.id] || 99;
return aPriority - bPriority;
});
});
return categories.filter(cat => cat.templates.length > 0);
}
async selectTemplate() {
console.clear();
console.log(chalk_1.default.bold.cyan('š Re-Shell Backend Template Selector\n'));
// First, select language/category
const { category } = await inquirer.prompt([
{
type: 'list',
name: 'category',
message: 'Select a programming language:',
choices: this.categories.map(cat => ({
name: `${cat.icon} ${cat.name} - ${cat.description}`,
value: cat.value,
short: cat.name
}))
}
]);
const selectedCategory = this.categories.find(cat => cat.value === category);
if (!selectedCategory)
return null;
console.clear();
console.log(chalk_1.default.bold.cyan(`š ${selectedCategory.name} Backend Frameworks\n`));
// Show templates for selected category
const choices = selectedCategory.templates.map(template => {
const tags = template.tags.slice(0, 3).join(', ');
const popularity = this.getPopularityStars(template.id);
return {
name: `${chalk_1.default.bold(template.displayName)}${popularity}\n ${chalk_1.default.gray(template.description || tags)}`,
value: template.id,
short: template.displayName
};
});
// Add back option
choices.push({
name: chalk_1.default.gray('ā Back to language selection'),
value: 'back',
short: 'Back'
});
const { templateId } = await inquirer.prompt([
{
type: 'list',
name: 'templateId',
message: 'Select a framework:',
choices,
pageSize: 15
}
]);
if (templateId === 'back') {
return this.selectTemplate();
}
const template = backend_1.backendTemplates[templateId];
// Show template details
console.clear();
this.showTemplateDetails(template);
const { confirm } = await inquirer.prompt([
{
type: 'confirm',
name: 'confirm',
message: 'Use this template?',
default: true
}
]);
if (!confirm) {
return this.selectTemplate();
}
return template;
}
async selectTemplateWithRecommendations(useCase) {
console.clear();
console.log(chalk_1.default.bold.cyan('š Re-Shell Backend Template Selector\n'));
const recommendations = this.getRecommendations(useCase);
if (recommendations.length > 0) {
console.log(chalk_1.default.yellow('š Recommended for your use case:\n'));
const { quickSelect } = await inquirer.prompt([
{
type: 'list',
name: 'quickSelect',
message: 'Select from recommendations or browse all:',
choices: [
...recommendations.map(rec => ({
name: `${chalk_1.default.bold.green('ā
')} ${rec.template.displayName} - ${rec.reason}`,
value: rec.template.id
})),
new inquirer.Separator(),
{
name: chalk_1.default.gray('Browse all templates ā'),
value: 'browse'
}
]
}
]);
if (quickSelect !== 'browse') {
const template = backend_1.backendTemplates[quickSelect];
this.showTemplateDetails(template);
const { confirm } = await inquirer.prompt([
{
type: 'confirm',
name: 'confirm',
message: 'Use this template?',
default: true
}
]);
if (confirm) {
return template;
}
}
}
return this.selectTemplate();
}
getRecommendations(useCase) {
const recommendations = [];
if (!useCase)
return recommendations;
const useCaseLower = useCase.toLowerCase();
// API Gateway
if (useCaseLower.includes('gateway') || useCaseLower.includes('proxy')) {
recommendations.push({
template: backend_1.backendTemplates.express,
reason: 'Lightweight and perfect for API gateways'
});
}
// Real-time
if (useCaseLower.includes('realtime') || useCaseLower.includes('websocket') || useCaseLower.includes('chat')) {
recommendations.push({
template: backend_1.backendTemplates.feathersjs,
reason: 'Built-in real-time support with Socket.io'
});
}
// Enterprise
if (useCaseLower.includes('enterprise') || useCaseLower.includes('large')) {
recommendations.push({
template: backend_1.backendTemplates.nestjs,
reason: 'Enterprise-grade with DI and modular architecture'
});
}
// High performance
if (useCaseLower.includes('performance') || useCaseLower.includes('fast') || useCaseLower.includes('speed')) {
recommendations.push({
template: backend_1.backendTemplates.gin,
reason: 'Extremely fast Go framework'
});
recommendations.push({
template: backend_1.backendTemplates.fastify,
reason: 'Fastest Node.js framework'
});
}
// GraphQL
if (useCaseLower.includes('graphql')) {
recommendations.push({
template: backend_1.backendTemplates['apollo-server'],
reason: 'Purpose-built for GraphQL APIs'
});
}
// CMS
if (useCaseLower.includes('cms') || useCaseLower.includes('content')) {
recommendations.push({
template: backend_1.backendTemplates.strapi,
reason: 'Headless CMS with admin panel'
});
recommendations.push({
template: backend_1.backendTemplates.django,
reason: 'Includes powerful admin interface'
});
}
// Microservices
if (useCaseLower.includes('microservice') || useCaseLower.includes('micro')) {
recommendations.push({
template: backend_1.backendTemplates.moleculer,
reason: 'Built specifically for microservices'
});
recommendations.push({
template: backend_1.backendTemplates.fastapi,
reason: 'Async Python perfect for microservices'
});
}
return recommendations.slice(0, 3); // Return top 3 recommendations
}
showTemplateDetails(template) {
console.log(chalk_1.default.bold.cyan(`\nš¦ ${template.displayName}\n`));
console.log(chalk_1.default.bold('Language:'), template.language);
console.log(chalk_1.default.bold('Framework:'), template.framework);
console.log(chalk_1.default.bold('Port:'), template.port);
console.log(chalk_1.default.bold('Tags:'), template.tags.join(', '));
if (template.dependencies) {
console.log(chalk_1.default.bold('\nKey Dependencies:'));
Object.entries(template.dependencies).slice(0, 5).forEach(([dep, version]) => {
console.log(` - ${dep}: ${version}`);
});
}
console.log(chalk_1.default.bold('\nFeatures:'));
this.getTemplateFeatures(template.id).forEach(feature => {
console.log(` ā ${feature}`);
});
console.log();
}
getTemplateFeatures(templateId) {
const features = {
express: ['Fast routing', 'Middleware support', 'Large ecosystem', 'REST APIs'],
nestjs: ['Dependency injection', 'TypeScript first', 'Modular architecture', 'Enterprise ready'],
fastify: ['High performance', 'Schema validation', 'TypeScript support', 'Plugin system'],
feathersjs: ['Real-time events', 'Service oriented', 'Database agnostic', 'Authentication'],
fastapi: ['Auto documentation', 'Type hints', 'Async support', 'High performance'],
django: ['Admin panel', 'ORM included', 'Authentication', 'Full-featured'],
gin: ['Blazing fast', 'Minimal footprint', 'Middleware support', 'JSON validation'],
strapi: ['Headless CMS', 'Admin panel', 'REST & GraphQL', 'Plugin system'],
'apollo-server': ['GraphQL first', 'Type safety', 'Federation', 'Subscriptions'],
moleculer: ['Microservices', 'Service discovery', 'Load balancing', 'Event driven']
};
return features[templateId] || ['Modern framework', 'Production ready', 'Active community'];
}
getPopularityStars(templateId) {
const popularity = {
express: 5,
nestjs: 5,
fastify: 4,
django: 5,
fastapi: 5,
flask: 4,
gin: 5,
feathersjs: 4,
strapi: 4,
'apollo-server': 4
};
const stars = popularity[templateId] || 3;
return ' ' + chalk_1.default.yellow('ā
'.repeat(stars)) + chalk_1.default.gray('ā
'.repeat(5 - stars));
}
}
exports.BackendTemplateSelector = BackendTemplateSelector;
// Interactive CLI function
async function selectBackendTemplate(useCase) {
const selector = new BackendTemplateSelector();
if (useCase) {
return selector.selectTemplateWithRecommendations(useCase);
}
return selector.selectTemplate();
}
// Quick selection by ID
function getBackendTemplate(templateId) {
return backend_1.backendTemplates[templateId] || null;
}
// List all templates
function listBackendTemplates() {
const selector = new BackendTemplateSelector();
console.log(chalk_1.default.bold.cyan('\nš Available Backend Templates\n'));
const categories = selector['categories']; // Access private property
categories.forEach(category => {
console.log(chalk_1.default.bold.yellow(`\n${category.icon} ${category.name}`));
console.log(chalk_1.default.gray('ā'.repeat(40)));
category.templates.forEach(template => {
const tags = template.tags.slice(0, 3).join(', ');
console.log(` ${chalk_1.default.bold(template.displayName.padEnd(15))} ${chalk_1.default.gray(tags)}`);
});
});
console.log();
}