UNPKG

arela

Version:

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

165 lines (160 loc) 5.28 kB
/** * Generate HTTP client from OpenAPI spec */ export function generateClient(spec, serviceName, baseURL) { const className = `${serviceName}Client`; let output = `/** * Auto-generated API client from OpenAPI spec * DO NOT EDIT - This file is generated by Arela * @see https://axios-http.com */ import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'; import * as types from './types'; import * as schemas from './schemas'; export interface ${className}Config { baseURL: string; token?: string; timeout?: number; } export class ${className} { private client: AxiosInstance; constructor(config: ${className}Config) { this.client = axios.create({ baseURL: config.baseURL, timeout: config.timeout || 30000, headers: { 'Content-Type': 'application/json', ...(config.token && { Authorization: \`Bearer \${config.token}\` }), }, }); } `; // Generate methods for each endpoint const methods = []; for (const [path, pathItem] of Object.entries(spec.paths)) { if (typeof pathItem !== 'object') continue; for (const [method, operation] of Object.entries(pathItem)) { if (!operation || typeof operation !== 'object') continue; if (method === 'parameters') continue; // Skip parameters key const methodCode = generateMethod(path, method, operation); if (methodCode) methods.push(methodCode); } } output += methods.join('\n\n'); output += '\n}\n'; return output; } function generateMethod(path, method, operation) { const methodName = generateMethodName(path, method, operation); const pathParams = extractPathParams(path); const queryParams = (operation.parameters || []).filter((p) => p.in === 'query'); const hasBody = ['post', 'put', 'patch'].includes(method.toLowerCase()); // Build parameter list const params = []; // Add path parameters for (const param of pathParams) { params.push(`${param}: string | number`); } // Add body parameter if (hasBody) { params.push('data?: any'); } // Add query parameters if (queryParams.length > 0) { params.push('params?: Record<string, any>'); } // Add config parameter params.push('config?: AxiosRequestConfig'); const parametersStr = params.join(', '); const methodUpper = method.toUpperCase(); // Build URL const urlTemplate = path.replace(/{([^}]+)}/g, '${$1}'); const urlExpr = `\`${urlTemplate}\``; // Build axios call let axiosCall = ''; const configParts = []; if (queryParams.length > 0) { configParts.push('params'); } configParts.push('...config'); const configStr = configParts.length > 0 ? `, { ${configParts.join(', ')} }` : ''; if (hasBody) { axiosCall = `this.client.${method.toLowerCase()}(${urlExpr}, data${configStr})`; } else { axiosCall = `this.client.${method.toLowerCase()}(${urlExpr}${configStr})`; } // Build return type const returnType = getReturnType(operation); const methodCode = ` /** * ${operation.summary || operation.description || `${methodUpper} ${path}`} */ async ${methodName}(${parametersStr}): Promise<${returnType}> { const response = await ${axiosCall}; return response.data; }`; return methodCode; } function generateMethodName(path, method, operation) { if (operation.operationId) { return camelCase(operation.operationId); } const parts = path.split('/').filter((p) => p && !p.startsWith('{')); const resource = parts[parts.length - 1] || 'resource'; const action = getActionFromMethod(method); return `${action}${capitalize(singularize(resource))}`; } function getReturnType(operation) { const responses = operation.responses || {}; // Try to find successful response const successCodes = ['200', '201']; for (const code of successCodes) { if (responses[code]) { return 'any'; // Simplified - could be enhanced with actual type extraction } } return 'any'; } function extractPathParams(path) { const matches = path.match(/{([^}]+)}/g); return matches ? matches.map((m) => m.slice(1, -1)) : []; } function getActionFromMethod(method) { const m = method.toLowerCase(); switch (m) { case 'get': return 'get'; case 'post': return 'create'; case 'put': return 'update'; case 'patch': return 'patch'; case 'delete': return 'delete'; default: return 'call'; } } function singularize(word) { if (word.endsWith('ies')) return word.slice(0, -3) + 'y'; if (word.endsWith('es')) return word.slice(0, -2); if (word.endsWith('s')) return word.slice(0, -1); return word; } function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); } function camelCase(str) { return str .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (index === 0 ? word.toLowerCase() : word.toUpperCase())) .replace(/\s+/g, ''); } //# sourceMappingURL=client-generator.js.map