@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
1,181 lines (1,168 loc) • 53.6 kB
JavaScript
"use strict";
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;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.DocumentationGenerator = void 0;
exports.generateDocumentation = generateDocumentation;
exports.generateAndWriteDocumentation = generateAndWriteDocumentation;
const events_1 = require("events");
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
class DocumentationGenerator extends events_1.EventEmitter {
constructor() {
super();
}
async generate(config) {
this.emit('generation:start', config);
const result = {
success: false,
documents: [],
errors: [],
warnings: []
};
try {
// Load project information
this.projectInfo = await this.loadProjectInfo(config.projectPath);
// Generate API documentation if requested
if (config.includeApi) {
try {
this.apiDocs = await this.generateApiDocumentation(config.projectPath);
}
catch (error) {
result.warnings?.push(`Failed to generate API documentation: ${error.message}`);
}
}
// Generate documents based on format
const formats = config.outputFormat === 'all'
? ['markdown', 'html', 'pdf']
: [config.outputFormat || 'markdown'];
for (const format of formats) {
const documents = await this.generateDocuments(config, format);
result.documents.push(...documents);
}
result.success = result.documents.length > 0;
this.emit('generation:complete', result);
return result;
}
catch (error) {
result.errors?.push(error.message);
this.emit('generation:error', error);
return result;
}
}
async loadProjectInfo(projectPath) {
const packageJsonPath = path.join(projectPath, 'package.json');
if (await fs.pathExists(packageJsonPath)) {
return await fs.readJson(packageJsonPath);
}
// Fallback for non-Node.js projects
return {
name: path.basename(projectPath),
description: 'Project documentation'
};
}
async generateDocuments(config, format) {
const documents = [];
// Main README
const readme = await this.generateReadme(config);
documents.push({
type: 'README',
path: path.join(config.projectPath, format === 'markdown' ? 'README.md' : `README.${format}`),
content: this.convertFormat(readme, 'markdown', format),
format
});
// API Documentation
if (config.includeApi && this.apiDocs) {
const apiDoc = await this.generateApiDoc(config);
documents.push({
type: 'API',
path: path.join(config.projectPath, 'docs', format === 'markdown' ? 'API.md' : `API.${format}`),
content: this.convertFormat(apiDoc, 'markdown', format),
format
});
}
// Examples Documentation
if (config.includeExamples) {
const examples = await this.generateExamplesDoc(config);
documents.push({
type: 'EXAMPLES',
path: path.join(config.projectPath, 'docs', format === 'markdown' ? 'EXAMPLES.md' : `EXAMPLES.${format}`),
content: this.convertFormat(examples, 'markdown', format),
format
});
}
// Changelog
if (config.includeChangelog) {
const changelog = await this.generateChangelog(config);
documents.push({
type: 'CHANGELOG',
path: path.join(config.projectPath, format === 'markdown' ? 'CHANGELOG.md' : `CHANGELOG.${format}`),
content: this.convertFormat(changelog, 'markdown', format),
format
});
}
// Contributing Guide
if (config.includeContributing) {
const contributing = await this.generateContributing(config);
documents.push({
type: 'CONTRIBUTING',
path: path.join(config.projectPath, format === 'markdown' ? 'CONTRIBUTING.md' : `CONTRIBUTING.${format}`),
content: this.convertFormat(contributing, 'markdown', format),
format
});
}
// Architecture Documentation
if (config.includeArchitecture) {
const architecture = await this.generateArchitectureDoc(config);
documents.push({
type: 'ARCHITECTURE',
path: path.join(config.projectPath, 'docs', format === 'markdown' ? 'ARCHITECTURE.md' : `ARCHITECTURE.${format}`),
content: this.convertFormat(architecture, 'markdown', format),
format
});
}
// License
if (config.includeLicense) {
const license = await this.generateLicense(config);
documents.push({
type: 'LICENSE',
path: path.join(config.projectPath, 'LICENSE'),
content: license,
format: 'markdown' // License is always plain text
});
}
return documents;
}
async generateReadme(config) {
const sections = [];
const info = this.projectInfo || { name: config.projectName };
// Header
sections.push(`# ${info.name}`);
sections.push('');
// Badges
const badges = this.generateBadges(config, info);
if (badges.length > 0) {
sections.push(badges.join(' '));
sections.push('');
}
// Description
const description = config.description || info.description || 'A project built with Re-Shell CLI';
sections.push(description);
sections.push('');
// Table of Contents
sections.push('## Table of Contents');
sections.push('');
sections.push('- [Features](#features)');
sections.push('- [Installation](#installation)');
sections.push('- [Usage](#usage)');
sections.push('- [Development](#development)');
if (config.includeApi)
sections.push('- [API Documentation](#api-documentation)');
if (config.includeExamples)
sections.push('- [Examples](#examples)');
if (config.includeArchitecture)
sections.push('- [Architecture](#architecture)');
sections.push('- [Testing](#testing)');
sections.push('- [Contributing](#contributing)');
sections.push('- [License](#license)');
sections.push('');
// Features
sections.push('## Features');
sections.push('');
sections.push(await this.generateFeaturesList(config));
sections.push('');
// Installation
sections.push('## Installation');
sections.push('');
sections.push('### Prerequisites');
sections.push('');
sections.push(this.generatePrerequisites(info));
sections.push('');
sections.push('### Setup');
sections.push('');
sections.push('```bash');
sections.push('# Clone the repository');
sections.push(`git clone ${info.repository || 'https://github.com/username/repo.git'}`);
sections.push(`cd ${info.name}`);
sections.push('');
sections.push('# Install dependencies');
sections.push(this.getInstallCommand(config.projectPath));
sections.push('```');
sections.push('');
// Usage
sections.push('## Usage');
sections.push('');
sections.push(await this.generateUsageSection(config, info));
sections.push('');
// Development
sections.push('## Development');
sections.push('');
sections.push(this.generateDevelopmentSection(info));
sections.push('');
// API Documentation
if (config.includeApi) {
sections.push('## API Documentation');
sections.push('');
sections.push('See [API.md](docs/API.md) for detailed API documentation.');
sections.push('');
}
// Examples
if (config.includeExamples) {
sections.push('## Examples');
sections.push('');
sections.push('See [EXAMPLES.md](docs/EXAMPLES.md) for usage examples.');
sections.push('');
}
// Architecture
if (config.includeArchitecture) {
sections.push('## Architecture');
sections.push('');
sections.push('See [ARCHITECTURE.md](docs/ARCHITECTURE.md) for architectural details.');
sections.push('');
}
// Testing
sections.push('## Testing');
sections.push('');
sections.push(this.generateTestingSection(info));
sections.push('');
// Contributing
sections.push('## Contributing');
sections.push('');
if (config.includeContributing) {
sections.push('Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.');
}
else {
sections.push('Contributions are welcome! Please feel free to submit a Pull Request.');
}
sections.push('');
// License
sections.push('## License');
sections.push('');
const license = config.license || info.license || 'MIT';
sections.push(`This project is licensed under the ${license} License${config.includeLicense ? ' - see the [LICENSE](LICENSE) file for details' : ''}.`);
sections.push('');
// Custom sections
if (config.customSections) {
const sortedSections = [...config.customSections].sort((a, b) => (a.order || 0) - (b.order || 0));
for (const section of sortedSections) {
sections.push(`## ${section.title}`);
sections.push('');
sections.push(section.content);
sections.push('');
}
}
// Footer
sections.push('---');
sections.push('');
sections.push(`Generated with ❤️ by [Re-Shell CLI](https://github.com/re-shell/cli)`);
return sections.join('\n');
}
generateBadges(config, info) {
const badges = [];
// Version badge
if (info.version) {
badges.push(``);
}
// License badge
const license = config.license || info.license;
if (license) {
badges.push(``);
}
// Build status badge (if CI is detected)
if (info.scripts?.test || info.scripts?.build) {
badges.push('');
}
// Coverage badge
if (info.scripts?.coverage) {
badges.push('');
}
// Node version badge
if (info.engines?.node) {
badges.push(``);
}
return badges;
}
async generateFeaturesList(config) {
const features = [];
// Analyze project to determine features
const projectPath = config.projectPath;
// Check for common features
if (await fs.pathExists(path.join(projectPath, 'tsconfig.json'))) {
features.push('✅ TypeScript support');
}
if (await fs.pathExists(path.join(projectPath, '.eslintrc.js')) ||
await fs.pathExists(path.join(projectPath, '.eslintrc.json'))) {
features.push('✅ ESLint configuration');
}
if (await fs.pathExists(path.join(projectPath, '.prettierrc'))) {
features.push('✅ Prettier code formatting');
}
if (await fs.pathExists(path.join(projectPath, 'jest.config.js')) ||
this.projectInfo?.devDependencies?.jest) {
features.push('✅ Jest testing framework');
}
if (await fs.pathExists(path.join(projectPath, 'docker-compose.yml')) ||
await fs.pathExists(path.join(projectPath, 'Dockerfile'))) {
features.push('✅ Docker support');
}
if (await fs.pathExists(path.join(projectPath, '.github/workflows'))) {
features.push('✅ GitHub Actions CI/CD');
}
// Add default features if none detected
if (features.length === 0) {
features.push('🚀 Fast and efficient');
features.push('📦 Easy to install');
features.push('🔧 Highly configurable');
features.push('📚 Well documented');
}
return features.map(f => `- ${f}`).join('\n');
}
generatePrerequisites(info) {
const prereqs = [];
if (info.engines?.node) {
prereqs.push(`- Node.js ${info.engines.node}`);
}
else {
prereqs.push('- Node.js >= 16.0.0');
}
if (info.engines?.npm) {
prereqs.push(`- npm ${info.engines.npm}`);
}
if (info.engines?.yarn) {
prereqs.push(`- Yarn ${info.engines.yarn}`);
}
return prereqs.join('\n');
}
getInstallCommand(projectPath) {
// Detect package manager
if (fs.existsSync(path.join(projectPath, 'pnpm-lock.yaml'))) {
return 'pnpm install';
}
else if (fs.existsSync(path.join(projectPath, 'yarn.lock'))) {
return 'yarn install';
}
else if (fs.existsSync(path.join(projectPath, 'bun.lockb'))) {
return 'bun install';
}
return 'npm install';
}
async generateUsageSection(config, info) {
const lines = [];
// Basic usage
if (info.scripts?.start) {
lines.push('### Running the application');
lines.push('');
lines.push('```bash');
lines.push('npm start');
lines.push('```');
lines.push('');
}
// Development mode
if (info.scripts?.dev || info.scripts?.develop) {
lines.push('### Development mode');
lines.push('');
lines.push('```bash');
lines.push(`npm run ${info.scripts.dev ? 'dev' : 'develop'}`);
lines.push('```');
lines.push('');
}
// CLI usage if applicable
if (info.bin) {
lines.push('### CLI Usage');
lines.push('');
lines.push('```bash');
const binName = typeof info.bin === 'string' ? info.name : Object.keys(info.bin)[0];
lines.push(`${binName} [command] [options]`);
lines.push('```');
lines.push('');
lines.push('For more information, run:');
lines.push('```bash');
lines.push(`${binName} --help`);
lines.push('```');
lines.push('');
}
// Configuration
lines.push('### Configuration');
lines.push('');
lines.push('Configuration options can be set in the following ways:');
lines.push('');
lines.push('1. Environment variables');
lines.push('2. Configuration file (`.env` or `config.json`)');
lines.push('3. Command line arguments');
lines.push('');
return lines.join('\n');
}
generateDevelopmentSection(info) {
const lines = [];
// Available scripts
if (info.scripts && Object.keys(info.scripts).length > 0) {
lines.push('### Available Scripts');
lines.push('');
for (const [script, command] of Object.entries(info.scripts)) {
lines.push(`- \`npm run ${script}\`: ${this.describeScript(script, command)}`);
}
lines.push('');
}
// Project structure
lines.push('### Project Structure');
lines.push('');
lines.push('```');
lines.push(this.generateProjectStructure());
lines.push('```');
return lines.join('\n');
}
describeScript(script, command) {
const descriptions = {
start: 'Start the application',
dev: 'Start development server with hot reload',
develop: 'Start development server',
build: 'Build the application for production',
test: 'Run tests',
'test:watch': 'Run tests in watch mode',
'test:coverage': 'Run tests with coverage report',
lint: 'Run linter',
'lint:fix': 'Run linter and fix issues',
format: 'Format code with Prettier',
clean: 'Clean build artifacts',
typecheck: 'Run TypeScript type checking',
docs: 'Generate documentation',
deploy: 'Deploy the application'
};
return descriptions[script] || command;
}
generateProjectStructure() {
return `├── src/ # Source files
│ ├── index.ts # Application entry point
│ ├── config/ # Configuration files
│ ├── controllers/ # Route controllers
│ ├── models/ # Data models
│ ├── services/ # Business logic
│ └── utils/ # Utility functions
├── tests/ # Test files
├── docs/ # Documentation
├── scripts/ # Build and deployment scripts
├── .env.example # Environment variables example
├── .gitignore # Git ignore file
├── package.json # Project metadata and dependencies
├── README.md # Project documentation
└── tsconfig.json # TypeScript configuration`;
}
generateTestingSection(info) {
const lines = [];
lines.push('Run the test suite using:');
lines.push('');
lines.push('```bash');
lines.push('# Run all tests');
lines.push(info.scripts?.test ? 'npm test' : 'npm test');
lines.push('');
if (info.scripts?.['test:watch']) {
lines.push('# Run tests in watch mode');
lines.push('npm run test:watch');
lines.push('');
}
if (info.scripts?.['test:coverage'] || info.scripts?.coverage) {
lines.push('# Run tests with coverage');
lines.push(`npm run ${info.scripts['test:coverage'] ? 'test:coverage' : 'coverage'}`);
lines.push('');
}
lines.push('```');
return lines.join('\n');
}
async generateApiDoc(config) {
if (!this.apiDocs) {
return '# API Documentation\n\nNo API documentation available.';
}
const sections = [];
sections.push('# API Documentation');
sections.push('');
sections.push(`API documentation for ${config.projectName}`);
sections.push('');
// Table of Contents
sections.push('## Table of Contents');
sections.push('');
if (this.apiDocs.modules.length > 0)
sections.push('- [Modules](#modules)');
if (this.apiDocs.classes.length > 0)
sections.push('- [Classes](#classes)');
if (this.apiDocs.interfaces.length > 0)
sections.push('- [Interfaces](#interfaces)');
if (this.apiDocs.functions.length > 0)
sections.push('- [Functions](#functions)');
if (this.apiDocs.types.length > 0)
sections.push('- [Types](#types)');
sections.push('');
// Modules
if (this.apiDocs.modules.length > 0) {
sections.push('## Modules');
sections.push('');
for (const module of this.apiDocs.modules) {
sections.push(`### ${module.name}`);
sections.push('');
if (module.description) {
sections.push(module.description);
sections.push('');
}
sections.push(`**Path:** \`${module.path}\``);
sections.push('');
if (module.exports.length > 0) {
sections.push('**Exports:**');
sections.push('');
for (const exp of module.exports) {
sections.push(`- \`${exp}\``);
}
sections.push('');
}
}
}
// Classes
if (this.apiDocs.classes.length > 0) {
sections.push('## Classes');
sections.push('');
for (const cls of this.apiDocs.classes) {
sections.push(`### ${cls.name}`);
sections.push('');
if (cls.description) {
sections.push(cls.description);
sections.push('');
}
if (cls.extends) {
sections.push(`**Extends:** \`${cls.extends}\``);
sections.push('');
}
if (cls.implements && cls.implements.length > 0) {
sections.push(`**Implements:** ${cls.implements.map(i => `\`${i}\``).join(', ')}`);
sections.push('');
}
// Constructor
if (cls.constructors.length > 0) {
sections.push('#### Constructor');
sections.push('');
for (const ctor of cls.constructors) {
sections.push(this.formatMethod(ctor, 'constructor'));
}
}
// Properties
if (cls.properties.length > 0) {
sections.push('#### Properties');
sections.push('');
sections.push('| Name | Type | Description |');
sections.push('|------|------|-------------|');
for (const prop of cls.properties) {
const visibility = prop.visibility !== 'public' ? `${prop.visibility} ` : '';
const modifiers = [
visibility,
prop.static ? 'static ' : '',
prop.readonly ? 'readonly ' : ''
].join('');
sections.push(`| ${modifiers}\`${prop.name}\` | \`${prop.type}\` | ${prop.description || '-'} |`);
}
sections.push('');
}
// Methods
if (cls.methods.length > 0) {
sections.push('#### Methods');
sections.push('');
for (const method of cls.methods) {
sections.push(this.formatMethod(method));
}
}
}
}
// Interfaces
if (this.apiDocs.interfaces.length > 0) {
sections.push('## Interfaces');
sections.push('');
for (const iface of this.apiDocs.interfaces) {
sections.push(`### ${iface.name}`);
sections.push('');
if (iface.description) {
sections.push(iface.description);
sections.push('');
}
if (iface.extends && iface.extends.length > 0) {
sections.push(`**Extends:** ${iface.extends.map(e => `\`${e}\``).join(', ')}`);
sections.push('');
}
// Properties
if (iface.properties.length > 0) {
sections.push('#### Properties');
sections.push('');
sections.push('| Name | Type | Required | Description |');
sections.push('|------|------|----------|-------------|');
for (const prop of iface.properties) {
sections.push(`| \`${prop.name}\` | \`${prop.type}\` | ${prop.optional ? 'No' : 'Yes'} | ${prop.description || '-'} |`);
}
sections.push('');
}
// Methods
if (iface.methods.length > 0) {
sections.push('#### Methods');
sections.push('');
for (const method of iface.methods) {
sections.push(this.formatMethod(method));
}
}
}
}
// Functions
if (this.apiDocs.functions.length > 0) {
sections.push('## Functions');
sections.push('');
for (const func of this.apiDocs.functions) {
sections.push(`### ${func.name}`);
sections.push('');
sections.push(this.formatFunction(func));
}
}
// Types
if (this.apiDocs.types.length > 0) {
sections.push('## Types');
sections.push('');
for (const type of this.apiDocs.types) {
sections.push(`### ${type.name}`);
sections.push('');
if (type.description) {
sections.push(type.description);
sections.push('');
}
sections.push('```typescript');
sections.push(`type ${type.name} = ${type.type};`);
sections.push('```');
sections.push('');
}
}
return sections.join('\n');
}
formatMethod(method, name) {
const lines = [];
const methodName = name || method.name;
// Signature
const visibility = method.visibility !== 'public' ? `${method.visibility} ` : '';
const modifiers = [
visibility,
method.static ? 'static ' : '',
method.async ? 'async ' : ''
].join('');
const params = method.parameters.map(p => {
const optional = p.optional ? '?' : '';
const defaultVal = p.defaultValue ? ` = ${p.defaultValue}` : '';
return `${p.name}${optional}: ${p.type}${defaultVal}`;
}).join(', ');
const returnType = method.returns ? `: ${method.returns.type}` : '';
lines.push(`##### ${modifiers}\`${methodName}(${params})${returnType}\``);
lines.push('');
if (method.description) {
lines.push(method.description);
lines.push('');
}
// Parameters
if (method.parameters.length > 0) {
lines.push('**Parameters:**');
lines.push('');
for (const param of method.parameters) {
lines.push(`- \`${param.name}\` (\`${param.type}\`)${param.optional ? ' - Optional' : ''} - ${param.description || 'No description'}`);
}
lines.push('');
}
// Returns
if (method.returns) {
lines.push('**Returns:**');
lines.push('');
lines.push(`\`${method.returns.type}\` - ${method.returns.description || 'No description'}`);
lines.push('');
}
// Examples
if (method.examples && method.examples.length > 0) {
lines.push('**Example:**');
lines.push('');
lines.push('```typescript');
lines.push(method.examples.join('\n'));
lines.push('```');
lines.push('');
}
return lines.join('\n');
}
formatFunction(func) {
const lines = [];
if (func.description) {
lines.push(func.description);
lines.push('');
}
// Signature
const params = func.parameters.map(p => {
const optional = p.optional ? '?' : '';
const defaultVal = p.defaultValue ? ` = ${p.defaultValue}` : '';
return `${p.name}${optional}: ${p.type}${defaultVal}`;
}).join(', ');
const returnType = func.returns ? `: ${func.returns.type}` : '';
lines.push('```typescript');
lines.push(`function ${func.name}(${params})${returnType}`);
lines.push('```');
lines.push('');
// Parameters
if (func.parameters.length > 0) {
lines.push('**Parameters:**');
lines.push('');
for (const param of func.parameters) {
lines.push(`- \`${param.name}\` (\`${param.type}\`)${param.optional ? ' - Optional' : ''} - ${param.description || 'No description'}`);
}
lines.push('');
}
// Returns
if (func.returns) {
lines.push('**Returns:**');
lines.push('');
lines.push(`\`${func.returns.type}\` - ${func.returns.description || 'No description'}`);
lines.push('');
}
// Examples
if (func.examples && func.examples.length > 0) {
lines.push('**Example:**');
lines.push('');
lines.push('```typescript');
lines.push(func.examples.join('\n'));
lines.push('```');
lines.push('');
}
return lines.join('\n');
}
async generateExamplesDoc(config) {
const sections = [];
sections.push('# Examples');
sections.push('');
sections.push(`Usage examples for ${config.projectName}`);
sections.push('');
// Basic example
sections.push('## Basic Usage');
sections.push('');
sections.push('```javascript');
sections.push(`const ${this.toCamelCase(config.projectName)} = require('${config.projectName}');`);
sections.push('');
sections.push('// Basic example');
sections.push(`const result = ${this.toCamelCase(config.projectName)}.doSomething();`);
sections.push('console.log(result);');
sections.push('```');
sections.push('');
// Advanced examples
sections.push('## Advanced Usage');
sections.push('');
// Configuration example
sections.push('### With Configuration');
sections.push('');
sections.push('```javascript');
sections.push(`const ${this.toCamelCase(config.projectName)} = require('${config.projectName}');`);
sections.push('');
sections.push('const config = {');
sections.push(' option1: true,');
sections.push(' option2: \'value\',');
sections.push(' nested: {');
sections.push(' setting: 42');
sections.push(' }');
sections.push('};');
sections.push('');
sections.push(`const instance = new ${this.toPascalCase(config.projectName)}(config);`);
sections.push('const result = await instance.process();');
sections.push('```');
sections.push('');
// Error handling example
sections.push('### Error Handling');
sections.push('');
sections.push('```javascript');
sections.push('try {');
sections.push(` const result = await ${this.toCamelCase(config.projectName)}.riskyOperation();`);
sections.push(' console.log(\'Success:\', result);');
sections.push('} catch (error) {');
sections.push(' console.error(\'Error:\', error.message);');
sections.push(' // Handle error appropriately');
sections.push('}');
sections.push('```');
sections.push('');
// Real-world example
sections.push('## Real-World Example');
sections.push('');
sections.push('Here\'s a complete example showing how to use this library in a real application:');
sections.push('');
sections.push('```javascript');
sections.push('const express = require(\'express\');');
sections.push(`const ${this.toCamelCase(config.projectName)} = require('${config.projectName}');`);
sections.push('');
sections.push('const app = express();');
sections.push(`const service = new ${this.toPascalCase(config.projectName)}({`);
sections.push(' // Configuration options');
sections.push('});');
sections.push('');
sections.push('app.post(\'/api/process\', async (req, res) => {');
sections.push(' try {');
sections.push(' const result = await service.process(req.body);');
sections.push(' res.json({ success: true, data: result });');
sections.push(' } catch (error) {');
sections.push(' res.status(500).json({ success: false, error: error.message });');
sections.push(' }');
sections.push('});');
sections.push('');
sections.push('app.listen(3000, () => {');
sections.push(' console.log(\'Server running on port 3000\');');
sections.push('});');
sections.push('```');
return sections.join('\n');
}
async generateChangelog(config) {
const sections = [];
sections.push('# Changelog');
sections.push('');
sections.push('All notable changes to this project will be documented in this file.');
sections.push('');
sections.push('The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),');
sections.push('and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).');
sections.push('');
// Current version
const version = this.projectInfo?.version || '1.0.0';
const date = new Date().toISOString().split('T')[0];
sections.push(`## [${version}] - ${date}`);
sections.push('');
sections.push('### Added');
sections.push('- Initial release');
sections.push('- Core functionality implementation');
sections.push('- Documentation');
sections.push('- Test suite');
sections.push('');
sections.push('### Changed');
sections.push('- N/A');
sections.push('');
sections.push('### Deprecated');
sections.push('- N/A');
sections.push('');
sections.push('### Removed');
sections.push('- N/A');
sections.push('');
sections.push('### Fixed');
sections.push('- N/A');
sections.push('');
sections.push('### Security');
sections.push('- N/A');
return sections.join('\n');
}
async generateContributing(config) {
const sections = [];
sections.push('# Contributing');
sections.push('');
sections.push(`We love your input! We want to make contributing to ${config.projectName} as easy and transparent as possible, whether it's:`);
sections.push('');
sections.push('- Reporting a bug');
sections.push('- Discussing the current state of the code');
sections.push('- Submitting a fix');
sections.push('- Proposing new features');
sections.push('- Becoming a maintainer');
sections.push('');
sections.push('## Development Process');
sections.push('');
sections.push('We use GitHub to host code, to track issues and feature requests, as well as accept pull requests.');
sections.push('');
sections.push('## Pull Requests');
sections.push('');
sections.push('1. Fork the repo and create your branch from `main`.');
sections.push('2. If you\'ve added code that should be tested, add tests.');
sections.push('3. If you\'ve changed APIs, update the documentation.');
sections.push('4. Ensure the test suite passes.');
sections.push('5. Make sure your code lints.');
sections.push('6. Issue that pull request!');
sections.push('');
sections.push('## Any contributions you make will be under the Software License');
sections.push('');
sections.push('In short, when you submit code changes, your submissions are understood to be under the same license that covers the project.');
sections.push('');
sections.push('## Report bugs using Github\'s issues');
sections.push('');
sections.push('We use GitHub issues to track public bugs. Report a bug by opening a new issue.');
sections.push('');
sections.push('## Write bug reports with detail, background, and sample code');
sections.push('');
sections.push('**Great Bug Reports** tend to have:');
sections.push('');
sections.push('- A quick summary and/or background');
sections.push('- Steps to reproduce');
sections.push(' - Be specific!');
sections.push(' - Give sample code if you can.');
sections.push('- What you expected would happen');
sections.push('- What actually happens');
sections.push('- Notes (possibly including why you think this might be happening, or stuff you tried that didn\'t work)');
sections.push('');
sections.push('## Code Style');
sections.push('');
sections.push('- 2 spaces for indentation rather than tabs');
sections.push('- 80 character line length');
sections.push('- Run `npm run lint` to check your code style');
sections.push('- Run `npm run format` to automatically format your code');
sections.push('');
sections.push('## License');
sections.push('');
sections.push(`By contributing, you agree that your contributions will be licensed under its ${config.license || 'MIT'} License.`);
return sections.join('\n');
}
async generateArchitectureDoc(config) {
const sections = [];
sections.push('# Architecture');
sections.push('');
sections.push(`This document describes the architecture of ${config.projectName}.`);
sections.push('');
sections.push('## Overview');
sections.push('');
sections.push('The application follows a modular architecture with clear separation of concerns.');
sections.push('');
sections.push('## Core Components');
sections.push('');
sections.push('### 1. Core Module');
sections.push('');
sections.push('The core module contains the fundamental business logic and domain models.');
sections.push('');
sections.push('```');
sections.push('core/');
sections.push('├── models/ # Domain models');
sections.push('├── services/ # Business logic');
sections.push('├── interfaces/ # Core interfaces');
sections.push('└── utils/ # Core utilities');
sections.push('```');
sections.push('');
sections.push('### 2. API Layer');
sections.push('');
sections.push('The API layer handles external communication and request/response processing.');
sections.push('');
sections.push('```');
sections.push('api/');
sections.push('├── controllers/ # Request handlers');
sections.push('├── middleware/ # Request processing');
sections.push('├── routes/ # Route definitions');
sections.push('└── validators/ # Input validation');
sections.push('```');
sections.push('');
sections.push('### 3. Data Layer');
sections.push('');
sections.push('The data layer manages data persistence and retrieval.');
sections.push('');
sections.push('```');
sections.push('data/');
sections.push('├── repositories/ # Data access');
sections.push('├── migrations/ # Database migrations');
sections.push('├── seeds/ # Test data');
sections.push('└── adapters/ # External service adapters');
sections.push('```');
sections.push('');
sections.push('## Design Patterns');
sections.push('');
sections.push('### Repository Pattern');
sections.push('Used for data access abstraction, allowing easy swapping of data sources.');
sections.push('');
sections.push('### Dependency Injection');
sections.push('Used throughout the application for loose coupling and testability.');
sections.push('');
sections.push('### Observer Pattern');
sections.push('Used for event-driven communication between components.');
sections.push('');
sections.push('## Data Flow');
sections.push('');
sections.push('```');
sections.push('Client Request');
sections.push(' ↓');
sections.push('API Gateway');
sections.push(' ↓');
sections.push('Controller');
sections.push(' ↓');
sections.push('Service Layer');
sections.push(' ↓');
sections.push('Data Layer');
sections.push(' ↓');
sections.push('Database');
sections.push('```');
sections.push('');
sections.push('## Security Considerations');
sections.push('');
sections.push('- Input validation at API boundaries');
sections.push('- Authentication and authorization middleware');
sections.push('- Rate limiting and DDoS protection');
sections.push('- Secure configuration management');
sections.push('- Regular security audits');
sections.push('');
sections.push('## Performance Optimization');
sections.push('');
sections.push('- Caching strategies at multiple levels');
sections.push('- Database query optimization');
sections.push('- Lazy loading and code splitting');
sections.push('- Horizontal scaling support');
sections.push('- Monitoring and performance metrics');
return sections.join('\n');
}
async generateLicense(config) {
const licenseType = config.license || this.projectInfo?.license || 'MIT';
const year = new Date().getFullYear();
const author = config.author || this.projectInfo?.author || 'Your Name';
const authorName = typeof author === 'string' ? author : author.name;
const licenses = {
MIT: `MIT License
Copyright (c) ${year} ${authorName}
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.`,
'Apache-2.0': `Copyright ${year} ${authorName}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.`,
'GPL-3.0': `Copyright (C) ${year} ${authorName}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.`,
ISC: `ISC License
Copyright (c) ${year}, ${authorName}
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.`
};
return licenses[licenseType] || licenses.MIT;
}
async generateApiDocumentation(projectPath) {
// This is a simplified API documentation generator
// In a real implementation, you would use tools like TypeDoc or JSDoc
const apiDocs = {
modules: [],
classes: [],
functions: [],
interfaces: [],
types: []
};
// Scan for TypeScript/JavaScript files
const sourceFiles = await this.findSourceFiles(projectPath);
for (const file of sourceFiles) {
try {
const content = await fs.readFile(file, 'utf8');
const relativePath = path.relative(projectPath, file);
// Extract module info
const moduleName = path.basename(file, path.extname(file));
apiDocs.modules.push({
name: moduleName,
path: relativePath,
exports: this.extractExports(content),
imports: this.extractImports(content)
});
// Extract other API elements (simplified)
// In practice, you'd use a proper AST parser
}
catch (error) {
// Skip files that can't be read
}
}
return apiDocs;
}
async findSourceFiles(projectPath) {
const files = [];
const srcDir = path.join(projectPath, 'src');
if (!await fs.pathExists(srcDir)) {
return files;
}
const walk = async (dir) => {
const entries = await fs.readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
await walk(fullPath);
}
else if (entry.isFile() && /\.(ts|js|tsx|jsx)$/.test(entry.name)) {
files.push(fullPath);
}
}
};
await walk(srcDir);
return files;
}
extractExports(content) {
const exports = [];
const exportRegex = /export\s+(?:const|let|var|function|class|interface|type|enum)\s+(\w+)/g;
let match;
while ((match = exportRegex.exec(content)) !== null) {
exports.push(match[1]);
}
return exports;
}
extractImports(content) {
const imports = [];
const importRegex = /import\s+.*?\s+from\s+['"](.+?)['"]/g;
let match;
while ((match = importRegex.exec(content)) !== null) {
imports.push(match[1]);
}
return imports;
}
convertFormat(content, from, to) {
if (from === to) {
return content;
}
// Simplified conversion - in practice, you'd use proper conversion libraries
if (from === 'markdown' && to === 'html') {
return this.markdownToHtml(content);
}
// For PDF, you'd typically use a library like puppeteer or wkhtmltopdf
return content;
}
markdownToHtml(markdown) {
// Very basic markdown