UNPKG

arela

Version:

AI-powered CTO with multi-agent orchestration, code summarization, visual testing (web + mobile) for blazing fast development.

91 lines (90 loc) 3.34 kB
/** * TypeScript client generator - main orchestrator */ import path from 'path'; import fs from 'fs-extra'; import yaml from 'yaml'; import { generateTypes } from './type-generator.js'; import { generateSchemas } from './schema-generator.js'; import { generateClient } from './client-generator.js'; export async function generateTypeScriptClient(contractPath, outputDir, baseURL) { const result = { success: false, filesGenerated: [], linesOfCode: 0, errors: [], }; try { // 1. Parse OpenAPI spec const spec = await parseOpenAPISpec(contractPath); const serviceName = normalizeServiceName(spec.info.title); const serviceDir = path.join(outputDir, serviceName.toLowerCase()); // 2. Ensure output directory exists await fs.ensureDir(serviceDir); // 3. Generate all files const generated = generateAllFiles(spec, serviceName, baseURL); // 4. Write files const typesPath = path.join(serviceDir, 'types.ts'); const schemasPath = path.join(serviceDir, 'schemas.ts'); const clientPath = path.join(serviceDir, 'client.ts'); const indexPath = path.join(serviceDir, 'index.ts'); await fs.writeFile(typesPath, generated.types); await fs.writeFile(schemasPath, generated.schemas); await fs.writeFile(clientPath, generated.client); await fs.writeFile(indexPath, generated.index); // 5. Calculate metrics const totalLines = generated.types.split('\n').length + generated.schemas.split('\n').length + generated.client.split('\n').length + generated.index.split('\n').length; result.success = true; result.filesGenerated = [typesPath, schemasPath, clientPath, indexPath]; result.linesOfCode = totalLines; } catch (error) { result.errors = [error instanceof Error ? error.message : String(error)]; } return result; } async function parseOpenAPISpec(contractPath) { const content = await fs.readFile(contractPath, 'utf-8'); if (contractPath.endsWith('.yaml') || contractPath.endsWith('.yml')) { return yaml.parse(content); } if (contractPath.endsWith('.json')) { return JSON.parse(content); } throw new Error(`Unsupported file format: ${contractPath}`); } function normalizeServiceName(title) { return title .replace(/\s+/g, '_') .replace(/[^a-zA-Z0-9_]/g, '') .replace(/_+/g, '_') .toLowerCase(); } function generateAllFiles(spec, serviceName, baseURL) { const types = generateTypes(spec); const schemas = generateSchemas(spec); const client = generateClient(spec, capitalize(serviceName), baseURL); const index = generateIndex(serviceName); return { types, schemas, client, index }; } function generateIndex(serviceName) { const className = capitalize(serviceName); return `/** * API Client exports * Auto-generated by Arela */ export * from './types'; export * from './schemas'; export { ${className}Client, type ${className}ClientConfig } from './client'; `; } function capitalize(str) { return str .split('_') .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) .join(''); } //# sourceMappingURL=typescript-generator.js.map