wrekenfile-converter
Version:
Convert OpenAPI and Postman specs into Wrekenfiles, with chunking for vector database storage
120 lines • 4.89 kB
JavaScript
;
/**
* Conversion quality metrics for Wrekenfile generation.
* Analyzes a generated Wrekenfile object and reports statistics
* so users understand what was converted and what was lost.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeConversionStats = computeConversionStats;
exports.formatConversionStats = formatConversionStats;
/**
* Compute conversion stats from a parsed Wrekenfile object.
* Call this after generating the wrekenfile but before serializing to YAML.
*
* @param wrekenfile - The wrekenfile object (with VERSION, METHODS, STRUCTS, etc.)
* @param preFilterStructCount - Number of structs before filterStructsByUsage (optional)
*/
function computeConversionStats(wrekenfile, preFilterStructCount) {
var _a, _b;
const methods = wrekenfile.METHODS || {};
const structs = wrekenfile.STRUCTS || {};
const warnings = [];
let methodCount = 0;
let methodsWithReturns = 0;
let methodsWithVoidReturns = 0;
let methodsWithErrors = 0;
let methodsWithAuth = 0;
let methodsWithInputs = 0;
const httpMethodCounts = {};
for (const [methodId, methodData] of Object.entries(methods)) {
methodCount++;
// HTTP method counts
const httpMethod = ((_a = methodData.HTTP) === null || _a === void 0 ? void 0 : _a.METHOD) || 'UNKNOWN';
httpMethodCounts[httpMethod] = (httpMethodCounts[httpMethod] || 0) + 1;
// Returns analysis
if (Array.isArray(methodData.RETURNS) && methodData.RETURNS.length > 0) {
methodsWithReturns++;
}
else {
methodsWithVoidReturns++;
// Only warn for GET methods with no returns — that's almost always a bug
if (httpMethod === 'GET') {
warnings.push(`${methodId}: GET endpoint has no RETURNS`);
}
}
// Errors
if (Array.isArray(methodData.ERRORS) && methodData.ERRORS.length > 0) {
methodsWithErrors++;
}
// Auth (case-insensitive header match — Wrekenfile headers can be emitted
// in any case by user-edited files or other converters)
const headers = ((_b = methodData.HTTP) === null || _b === void 0 ? void 0 : _b.HEADERS) || {};
const normalizedHeaderKeys = Object.keys(headers).map((k) => k.toLowerCase());
if (normalizedHeaderKeys.includes('authorization') ||
normalizedHeaderKeys.includes('x-api-key')) {
methodsWithAuth++;
}
// Inputs
if (Array.isArray(methodData.INPUTS) && methodData.INPUTS.length > 0) {
methodsWithInputs++;
}
}
const structCount = Object.keys(structs).length;
const structsPruned = preFilterStructCount !== undefined
? preFilterStructCount - structCount
: 0;
if (structsPruned > 0) {
warnings.push(`${structsPruned} unused struct(s) pruned`);
}
if (methodCount > 0 && methodsWithReturns === 0) {
warnings.push('No methods have response types — LLMs will not be able to parse API responses');
}
if (methodCount > 0 && methodsWithAuth === 0 && methodCount > 3) {
warnings.push('No methods have authentication headers — verify if this API requires auth');
}
return {
methodCount,
methodsWithReturns,
methodsWithVoidReturns,
methodsWithErrors,
structCount,
structsPruned,
httpMethodCounts,
methodsWithAuth,
methodsWithInputs,
warnings,
};
}
/**
* Format conversion stats as a human-readable summary string.
*/
function formatConversionStats(stats) {
const lines = [];
lines.push(`Conversion Summary:`);
lines.push(` Methods: ${stats.methodCount}`);
const httpParts = Object.entries(stats.httpMethodCounts)
.map(([method, count]) => `${method}: ${count}`)
.join(', ');
if (httpParts) {
lines.push(` HTTP methods: ${httpParts}`);
}
lines.push(` With response types: ${stats.methodsWithReturns}/${stats.methodCount}`);
if (stats.methodsWithVoidReturns > 0) {
lines.push(` Void (no response type): ${stats.methodsWithVoidReturns}`);
}
lines.push(` With error handling: ${stats.methodsWithErrors}/${stats.methodCount}`);
lines.push(` With auth headers: ${stats.methodsWithAuth}/${stats.methodCount}`);
lines.push(` With inputs: ${stats.methodsWithInputs}/${stats.methodCount}`);
lines.push(` Structs: ${stats.structCount}`);
if (stats.structsPruned > 0) {
lines.push(` Structs pruned (unused): ${stats.structsPruned}`);
}
if (stats.warnings.length > 0) {
lines.push(` Warnings:`);
for (const warning of stats.warnings) {
lines.push(` - ${warning}`);
}
}
return lines.join('\n');
}
//# sourceMappingURL=conversion-stats.js.map