feat: add HTTP API endpoints for headless mode
This commit is contained in:
@@ -59,10 +59,48 @@ function getIndexPath() {
|
||||
}
|
||||
|
||||
function startHttpServer(port) {
|
||||
const distPath = app.isPackaged
|
||||
const distPath = app.isPackaged
|
||||
? path.join(__dirname, '..', 'dist')
|
||||
: path.join(__dirname, '..', 'dist');
|
||||
|
||||
|
||||
// Reusable function for listing docs files
|
||||
function listDocsFilesHandler(basePath) {
|
||||
const docsPath = path.join(basePath, 'api');
|
||||
if (!fs.existsSync(docsPath)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const result = [];
|
||||
|
||||
function walkDir(dir, baseDir) {
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
walkDir(fullPath, baseDir);
|
||||
} else if (entry.name.endsWith('.md')) {
|
||||
const relativePath = path.relative(baseDir, fullPath);
|
||||
result.push({
|
||||
name: entry.name.replace('.md', ''),
|
||||
path: fullPath,
|
||||
relativePath: relativePath.replace(/\\/g, '/')
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
walkDir(docsPath, docsPath);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Reusable function for reading doc file
|
||||
function readDocFileHandler(filePath) {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
return null;
|
||||
}
|
||||
return fs.readFileSync(filePath, 'utf-8');
|
||||
}
|
||||
|
||||
const mimeTypes = {
|
||||
'.html': 'text/html',
|
||||
'.js': 'application/javascript',
|
||||
@@ -81,8 +119,47 @@ function startHttpServer(port) {
|
||||
};
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
// Handle API endpoints
|
||||
const urlObj = new URL(req.url, `http://localhost:${port}`);
|
||||
if (urlObj.pathname === '/api/list-docs-files') {
|
||||
const basePath = urlObj.searchParams.get('basePath');
|
||||
if (!basePath) {
|
||||
res.writeHead(400, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: 'basePath is required' }));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const files = listDocsFilesHandler(basePath);
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify(files));
|
||||
} catch (err) {
|
||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: err.message }));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (urlObj.pathname === '/api/read-doc-file') {
|
||||
const filePathParam = urlObj.searchParams.get('path');
|
||||
if (!filePathParam) {
|
||||
res.writeHead(400, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: 'path is required' }));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const content = readDocFileHandler(filePathParam);
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ content }));
|
||||
} catch (err) {
|
||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: err.message }));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Serve static files
|
||||
let filePath = path.join(distPath, req.url === '/' ? 'index.html' : req.url);
|
||||
|
||||
|
||||
const ext = path.extname(filePath);
|
||||
const contentType = mimeTypes[ext] || 'application/octet-stream';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user