UNPKG

breathe-api

Version:

Model Context Protocol server for Breathe HR APIs with Swagger/OpenAPI support - also works with custom APIs

138 lines 5.55 kB
export async function generateTypesFromSchema(spec) { const types = []; const schemas = spec.components?.schemas || spec.definitions || {}; types.push('// Auto-generated TypeScript types from Swagger/OpenAPI spec'); types.push(''); for (const [name, schema] of Object.entries(schemas)) { types.push(generateInterface(name, schema)); types.push(''); } if (spec.paths) { types.push('// API Operation Types'); types.push(''); for (const [path, pathItem] of Object.entries(spec.paths)) { for (const [method, operation] of Object.entries(pathItem)) { if (['get', 'post', 'put', 'delete', 'patch'].includes(method.toLowerCase())) { const opTypes = generateOperationTypes(path, method, operation); if (opTypes) { types.push(opTypes); types.push(''); } } } } } return types.join('\n'); } function generateInterface(name, schema) { const lines = []; lines.push(`export interface ${sanitizeName(name)} {`); if (schema.type === 'object' && schema.properties) { for (const [propName, propSchema] of Object.entries(schema.properties)) { const required = schema.required?.includes(propName) || false; const optional = required ? '' : '?'; const type = getTypeFromSchema(propSchema); lines.push(` ${propName}${optional}: ${type};`); } } else if (schema.enum) { return `export type ${sanitizeName(name)} = ${schema.enum.map((v) => `'${v}'`).join(' | ')};`; } lines.push('}'); return lines.join('\n'); } function generateOperationTypes(_path, _method, operation) { if (!operation.operationId) return null; const lines = []; const opName = sanitizeName(operation.operationId); const hasParams = operation.parameters && operation.parameters.length > 0; const hasBody = operation.requestBody?.content; if (hasParams || hasBody) { lines.push(`export interface ${opName}Request {`); if (hasParams) { const queryParams = operation.parameters.filter((p) => p.in === 'query'); const pathParams = operation.parameters.filter((p) => p.in === 'path'); const headerParams = operation.parameters.filter((p) => p.in === 'header'); if (pathParams.length > 0) { lines.push(' params: {'); for (const param of pathParams) { const required = param.required ? '' : '?'; const schema = param.schema || {}; lines.push(` ${param.name}${required}: ${getTypeFromSchema(schema)};`); } lines.push(' };'); } if (queryParams.length > 0) { lines.push(' query?: {'); for (const param of queryParams) { const required = param.required ? '' : '?'; const schema = param.schema || {}; lines.push(` ${param.name}${required}: ${getTypeFromSchema(schema)};`); } lines.push(' };'); } if (headerParams.length > 0) { lines.push(' headers?: {'); for (const param of headerParams) { const required = param.required ? '' : '?'; const schema = param.schema || {}; lines.push(` ${param.name}${required}: ${getTypeFromSchema(schema)};`); } lines.push(' };'); } } if (hasBody) { const content = operation.requestBody.content || {}; const firstContent = Object.values(content)[0]; const bodySchema = firstContent?.schema; if (bodySchema) { lines.push(` body: ${getTypeFromSchema(bodySchema)};`); } } lines.push('}'); lines.push(''); } if (operation.responses) { const successResponse = operation.responses['200'] || operation.responses['201']; if (successResponse?.content) { const content = successResponse.content || {}; const firstContent = Object.values(content)[0]; const responseSchema = firstContent?.schema; if (responseSchema) { lines.push(`export type ${opName}Response = ${getTypeFromSchema(responseSchema)};`); } } } return lines.join('\n'); } function getTypeFromSchema(schema) { if (!schema) return 'any'; if (schema.$ref) { const refName = schema.$ref.split('/').pop(); return sanitizeName(refName); } switch (schema.type) { case 'string': return schema.enum ? schema.enum.map((v) => `'${v}'`).join(' | ') : 'string'; case 'number': case 'integer': return 'number'; case 'boolean': return 'boolean'; case 'array': return `Array<${getTypeFromSchema(schema.items)}>`; case 'object': if (schema.additionalProperties) { return `Record<string, ${getTypeFromSchema(schema.additionalProperties)}>`; } return 'any'; default: return 'any'; } } function sanitizeName(name) { return name.replace(/[^a-zA-Z0-9_]/g, ''); } //# sourceMappingURL=type-generator.js.map