81 lines
2.4 KiB
JavaScript
81 lines
2.4 KiB
JavaScript
const express = require('express');
|
|
const path = require('path');
|
|
const yaml = require('js-yaml');
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3000;
|
|
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
app.use(express.json({ limit: '2mb' }));
|
|
|
|
app.get('/api/health', (req, res) => {
|
|
res.json({ status: 'ok' });
|
|
});
|
|
|
|
function buildGraphFromPaths(pathsObject) {
|
|
const httpMethods = new Set(['get','put','post','delete','options','head','patch','trace']);
|
|
const nodeIdSet = new Set();
|
|
const linkKeySet = new Set();
|
|
const nodes = [];
|
|
const links = [];
|
|
const endpoints = [];
|
|
|
|
for (const pathKey of Object.keys(pathsObject || {})) {
|
|
const pathItem = pathsObject[pathKey] || {};
|
|
// Collect endpoints
|
|
for (const method of Object.keys(pathItem)) {
|
|
const lower = method.toLowerCase();
|
|
if (httpMethods.has(lower)) {
|
|
endpoints.push({ method: lower.toUpperCase(), path: pathKey });
|
|
}
|
|
}
|
|
// Build nodes/links from URL segments
|
|
const segments = pathKey.split('/').filter(Boolean);
|
|
if (segments.length === 0) continue;
|
|
|
|
// Ensure nodes
|
|
for (const seg of segments) {
|
|
if (!nodeIdSet.has(seg)) {
|
|
nodeIdSet.add(seg);
|
|
nodes.push({ id: seg });
|
|
}
|
|
}
|
|
|
|
// Create sequential links along the path
|
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
const source = segments[i];
|
|
const target = segments[i + 1];
|
|
const key = `${source}|${target}`;
|
|
if (!linkKeySet.has(key)) {
|
|
linkKeySet.add(key);
|
|
links.push({ source, target });
|
|
}
|
|
}
|
|
}
|
|
|
|
return { nodes, links, endpoints };
|
|
}
|
|
|
|
app.post('/api/parse', (req, res) => {
|
|
try {
|
|
const { yaml: yamlText } = req.body || {};
|
|
if (typeof yamlText !== 'string' || yamlText.trim() === '') {
|
|
return res.status(400).json({ error: 'Missing yaml string in body' });
|
|
}
|
|
const spec = yaml.load(yamlText);
|
|
if (!spec || typeof spec !== 'object') {
|
|
return res.status(400).json({ error: 'Invalid YAML content' });
|
|
}
|
|
|
|
const pathsObject = spec.paths || {};
|
|
const graph = buildGraphFromPaths(pathsObject);
|
|
res.json({ graph, info: { title: spec.info && spec.info.title, version: spec.info && spec.info.version } });
|
|
} catch (err) {
|
|
res.status(400).json({ error: err.message || 'Failed to parse YAML' });
|
|
}
|
|
});
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`Server listening on http://localhost:${PORT}`);
|
|
});
|