clqms-be/public/bundle-api-docs.js

97 lines
3.2 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* OpenAPI Documentation Bundler - Node.js Version
*
* This script merges the modular OpenAPI specification files into a single
* api-docs.bundled.yaml file that can be served to Swagger UI.
*
* It merges paths from the paths/ directory and then uses Redocly CLI to resolve
* all $ref references into inline definitions.
*
* Usage: node bundle-api-docs.js
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const publicDir = __dirname;
const pathsDir = path.join(publicDir, 'paths');
const tempFile = path.join(publicDir, 'api-docs.merged.yaml');
const outputFile = path.join(publicDir, 'api-docs.bundled.yaml');
// Read the base api-docs.yaml
const apiDocsPath = path.join(publicDir, 'api-docs.yaml');
let apiDocsContent = fs.readFileSync(apiDocsPath, 'utf8');
// Parse YAML manually (simple approach - looking for paths: {})
const pathsMatch = apiDocsContent.match(/^paths:\s*\{\}/m);
if (!pathsMatch) {
console.error('Could not find empty paths section in api-docs.yaml');
process.exit(1);
}
// Read all path files
const pathFiles = fs.readdirSync(pathsDir)
.filter(f => f.endsWith('.yaml'))
.map(f => path.join(pathsDir, f));
console.log(`Found ${pathFiles.length} path files to merge...`);
// Merge all paths content
let mergedPaths = [];
for (const filepath of pathFiles) {
const filename = path.basename(filepath);
try {
let content = fs.readFileSync(filepath, 'utf8');
// Fix relative paths: ../components/ -> ./components/
// because paths are now at the root level after merging
content = content.replace(/\.\.\/components\//g, './components/');
mergedPaths.push(`# From: ${filename}\n${content}`);
console.log(` [OK] Merged paths from ${filename}`);
} catch (e) {
console.log(` [WARN] Failed to read ${filename}: ${e.message}`);
}
}
// Replace empty paths with merged paths
const pathsYaml = mergedPaths.join('\n\n');
const mergedContent = apiDocsContent.replace(
/^paths:\s*\{\}/m,
`paths:\n${pathsYaml.split('\n').map(line => ' ' + line).join('\n')}`
);
// Write merged file (still has $refs)
fs.writeFileSync(tempFile, mergedContent, 'utf8');
console.log(`\n[SUCCESS] Merged paths into: ${tempFile}`);
// Now use Redocly CLI to resolve all $ref references
console.log('\nResolving $ref references with Redocly CLI...');
try {
execSync(`redocly bundle "${tempFile}" -o "${outputFile}"`, {
cwd: publicDir,
stdio: 'inherit'
});
console.log(`\n[SUCCESS] Resolved all $ref references to: ${outputFile}`);
// Clean up temp file
fs.unlinkSync(tempFile);
console.log(`[CLEANUP] Removed temp file: ${tempFile}`);
// Show stats
const stats = fs.statSync(outputFile);
console.log(`\n${'='.repeat(60)}`);
console.log('Bundling complete!');
console.log(` Output: ${outputFile}`);
console.log(` Size: ${(stats.size / 1024).toFixed(1)} KB`);
console.log(`\nYou can now serve this file to Swagger UI.`);
console.log(`${'='.repeat(60)}`);
} catch (e) {
console.error(`\n[ERROR] Failed to run Redocly CLI: ${e.message}`);
console.error('Make sure Redocly CLI is installed: npm install -g @redocly/cli');
process.exit(1);
}