- Handle type arrays: type: ['string', 'null'] → string | null - Handle const keyword: const: "active" → 'active' literal type - Handle nullable (OpenAPI 3.0 backward compatibility) - Extract and display webhook count in metadata - Add security escaping for string literals and JSDoc comments - Add OpenAPI 3.1 test fixture and 12 unit tests Fixes #365 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
149 lines
3.8 KiB
TypeScript
149 lines
3.8 KiB
TypeScript
import type { EndpointInfo, ParsedSpec, ValidationResult, SchemaInfo } from '../lib/types.js';
|
|
|
|
export function formatMetadata(metadata: ParsedSpec): string {
|
|
const lines = [
|
|
`# ${metadata.title}`,
|
|
`Version: ${metadata.version}`,
|
|
];
|
|
|
|
if (metadata.description) {
|
|
lines.push(`Description: ${metadata.description}`);
|
|
}
|
|
|
|
lines.push('');
|
|
lines.push(`## Statistics`);
|
|
lines.push(`- Paths: ${metadata.pathCount}`);
|
|
lines.push(`- Operations: ${metadata.operationCount}`);
|
|
lines.push(`- Schemas: ${metadata.schemaCount}`);
|
|
if (metadata.webhookCount !== undefined && metadata.webhookCount > 0) {
|
|
lines.push(`- Webhooks: ${metadata.webhookCount}`);
|
|
}
|
|
|
|
if (metadata.servers.length > 0) {
|
|
lines.push('');
|
|
lines.push(`## Servers`);
|
|
metadata.servers.forEach(s => lines.push(`- ${s}`));
|
|
}
|
|
|
|
if (metadata.tags.length > 0) {
|
|
lines.push('');
|
|
lines.push(`## Tags`);
|
|
metadata.tags.forEach(t => lines.push(`- ${t}`));
|
|
}
|
|
|
|
return lines.join('\n');
|
|
}
|
|
|
|
export function formatValidation(result: ValidationResult): string {
|
|
const lines: string[] = [];
|
|
|
|
if (result.valid) {
|
|
lines.push('Validation: PASSED');
|
|
} else {
|
|
lines.push('Validation: FAILED');
|
|
}
|
|
|
|
if (result.errors.length > 0) {
|
|
lines.push('');
|
|
lines.push('## Errors');
|
|
for (const err of result.errors) {
|
|
const path = err.path ? `[${err.path}] ` : '';
|
|
lines.push(`- ${path}${err.message}`);
|
|
}
|
|
}
|
|
|
|
if (result.warnings.length > 0) {
|
|
lines.push('');
|
|
lines.push('## Warnings');
|
|
for (const warn of result.warnings) {
|
|
const path = warn.path ? `[${warn.path}] ` : '';
|
|
lines.push(`- ${path}${warn.message}`);
|
|
}
|
|
}
|
|
|
|
return lines.join('\n');
|
|
}
|
|
|
|
export function formatEndpoints(endpoints: EndpointInfo[]): string {
|
|
if (endpoints.length === 0) {
|
|
return 'No endpoints found matching criteria.';
|
|
}
|
|
|
|
const lines = [`Found ${endpoints.length} endpoint(s):`, ''];
|
|
|
|
for (const ep of endpoints) {
|
|
lines.push(`## ${ep.method.toUpperCase()} ${ep.path}`);
|
|
|
|
if (ep.operationId) {
|
|
lines.push(`Operation ID: ${ep.operationId}`);
|
|
}
|
|
|
|
if (ep.summary) {
|
|
lines.push(`Summary: ${ep.summary}`);
|
|
}
|
|
|
|
if (ep.tags.length > 0) {
|
|
lines.push(`Tags: ${ep.tags.join(', ')}`);
|
|
}
|
|
|
|
if (ep.parameters.length > 0) {
|
|
lines.push('');
|
|
lines.push('### Parameters');
|
|
for (const param of ep.parameters) {
|
|
const required = param.required ? ' (required)' : '';
|
|
lines.push(`- **${param.name}** [${param.in}]${required}`);
|
|
if (param.description) {
|
|
lines.push(` ${param.description}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ep.requestBody) {
|
|
lines.push('');
|
|
lines.push('### Request Body');
|
|
const required = ep.requestBody.required ? ' (required)' : '';
|
|
lines.push(`Content types${required}: ${ep.requestBody.contentTypes.join(', ')}`);
|
|
if (ep.requestBody.description) {
|
|
lines.push(ep.requestBody.description);
|
|
}
|
|
}
|
|
|
|
if (ep.responses.length > 0) {
|
|
lines.push('');
|
|
lines.push('### Responses');
|
|
for (const resp of ep.responses) {
|
|
lines.push(`- **${resp.statusCode}**: ${resp.description || 'No description'}`);
|
|
}
|
|
}
|
|
|
|
lines.push('');
|
|
}
|
|
|
|
return lines.join('\n');
|
|
}
|
|
|
|
export function formatSchema(schema: SchemaInfo): string {
|
|
const lines = [
|
|
`# ${schema.name}`,
|
|
];
|
|
|
|
if (schema.description) {
|
|
lines.push(schema.description);
|
|
}
|
|
|
|
if (schema.type) {
|
|
lines.push(`Type: ${schema.type}`);
|
|
}
|
|
|
|
lines.push('');
|
|
lines.push('## Schema');
|
|
lines.push('```json');
|
|
lines.push(JSON.stringify(schema.schema, null, 2));
|
|
lines.push('```');
|
|
|
|
return lines.join('\n');
|
|
}
|
|
|
|
export function formatTypes(types: string): string {
|
|
return ['## Generated TypeScript Types', '', '```typescript', types, '```'].join('\n');
|
|
}
|