221 lines
6.6 KiB
JavaScript
221 lines
6.6 KiB
JavaScript
import express from 'express';
|
|
import cors from 'cors';
|
|
import { exec } from 'child_process';
|
|
import { promisify } from 'util';
|
|
import fs from 'fs-extra';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const execAsync = promisify(exec);
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const app = express();
|
|
const PORT = process.env.API_PORT || 3001;
|
|
|
|
// Enable CORS for all origins
|
|
app.use(cors({
|
|
origin: '*',
|
|
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
allowedHeaders: ['Content-Type', 'Authorization']
|
|
}));
|
|
|
|
app.use(express.json());
|
|
|
|
// Logging middleware
|
|
app.use((req, res, next) => {
|
|
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
|
|
next();
|
|
});
|
|
|
|
// Health check endpoint
|
|
app.get('/health', (req, res) => {
|
|
res.json({
|
|
status: 'ok',
|
|
timestamp: new Date().toISOString(),
|
|
services: {
|
|
api: 'running',
|
|
vitepress: 'running'
|
|
}
|
|
});
|
|
});
|
|
|
|
// Export PDF endpoint
|
|
app.get('/export-pdf', async (req, res) => {
|
|
const docsPath = process.env.DOCS_PATH || '/app/docs';
|
|
const pdfFileName = req.query.fileName || `export-${Date.now()}.pdf`;
|
|
const vitepressPort = process.env.VITEPRESS_PORT || 3000;
|
|
|
|
console.log(`[${new Date().toISOString()}] Starting PDF export...`);
|
|
console.log(`Docs path: ${docsPath}`);
|
|
console.log(`PDF output: ${path.join(docsPath, pdfFileName)}`);
|
|
console.log(`VitePress port: ${vitepressPort}`);
|
|
|
|
try {
|
|
// Ensure PDF directory exists
|
|
await fs.ensureDir(docsPath);
|
|
|
|
// Clean old dist directory
|
|
const distDir = path.join(docsPath, '.vitepress', 'dist');
|
|
console.log('Cleaning old dist directory...');
|
|
await fs.remove(distDir).catch(() => {});
|
|
|
|
// Build the VitePress site
|
|
/*
|
|
console.log('Building VitePress site...');
|
|
try {
|
|
await execAsync('npm run docs:build', {
|
|
cwd: '/app',
|
|
stdio: 'inherit',
|
|
timeout: 120000 // 2 minutes timeout
|
|
});
|
|
} catch (buildError) {
|
|
console.error('Build warning/error:', buildError.message);
|
|
// Continue anyway, sometimes there are non-fatal warnings
|
|
}
|
|
*/
|
|
|
|
// Run PDF export (VitePress preview is already running)
|
|
console.log('Starting PDF export using running VitePress server...');
|
|
|
|
const exportEnv = {
|
|
...process.env,
|
|
NODE_ENV: 'development'
|
|
};
|
|
|
|
try {
|
|
/*
|
|
console.log('Installing vitepress-export-pdf...');
|
|
await execAsync('npm install vitepress-export-pdf -D', {
|
|
cwd: '/app',
|
|
stdio: 'inherit',
|
|
env: exportEnv,
|
|
timeout: 120000
|
|
});
|
|
*/
|
|
|
|
console.log('Running export-pdf...');
|
|
await execAsync('npm run export-pdf', {
|
|
cwd: '/app',
|
|
stdio: 'inherit',
|
|
env: exportEnv,
|
|
timeout: 180000,
|
|
maxBuffer: 1024 * 1024 * 100
|
|
});
|
|
} catch (exportError) {
|
|
console.error('Export command failed:', exportError.message);
|
|
throw new Error(`PDF export failed: ${exportError.message}`);
|
|
}
|
|
|
|
// Verify PDF was created
|
|
const pdfPath = path.join(docsPath, pdfFileName);
|
|
const pdfExists = await fs.pathExists(pdfPath);
|
|
|
|
if (!pdfExists) {
|
|
// Try to find any PDF file in the directory
|
|
const files = await fs.readdir(docsPath);
|
|
const pdfFiles = files.filter(f => f.endsWith('.pdf'));
|
|
|
|
if (pdfFiles.length > 0) {
|
|
console.log(`PDF found with different name: ${pdfFiles[0]}`);
|
|
const stats = await fs.stat(path.join(docsPath, pdfFiles[0]));
|
|
|
|
console.log(`[${new Date().toISOString()}] PDF export completed successfully!`);
|
|
console.log(`PDF size: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
|
|
|
|
return res.json({
|
|
success: true,
|
|
message: 'PDF exported successfully',
|
|
pdfPath: path.join(docsPath, pdfFiles[0]),
|
|
pdfUrl: `${pdfFiles[0]}`,
|
|
fileName: pdfFiles[0],
|
|
fileSize: stats.size,
|
|
fileSizeMB: (stats.size / 1024 / 1024).toFixed(2)
|
|
});
|
|
} else {
|
|
throw new Error('PDF file was not created');
|
|
}
|
|
}
|
|
|
|
const stats = await fs.stat(pdfPath);
|
|
|
|
console.log(`[${new Date().toISOString()}] PDF export completed successfully!`);
|
|
console.log(`PDF path: ${pdfPath}`);
|
|
console.log(`PDF size: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'PDF exported successfully',
|
|
pdfPath: pdfPath,
|
|
pdfUrl: `${pdfFileName}`,
|
|
fileName: pdfFileName,
|
|
fileSize: stats.size,
|
|
fileSizeMB: (stats.size / 1024 / 1024).toFixed(2)
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error(`[${new Date().toISOString()}] PDF export failed:`, error);
|
|
|
|
res.status(500).json({
|
|
success: false,
|
|
error: error.message,
|
|
stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
|
|
});
|
|
}
|
|
});
|
|
|
|
// List all PDF files
|
|
app.get('/pdf-files', async (req, res) => {
|
|
const docsPath = process.env.DOCS_PATH || '/app/docs';
|
|
|
|
try {
|
|
await fs.ensureDir(docsPath);
|
|
const files = await fs.readdir(docsPath);
|
|
const pdfFiles = files.filter(f => f.endsWith('.pdf'));
|
|
|
|
const fileDetails = await Promise.all(
|
|
pdfFiles.map(async (file) => {
|
|
const stats = await fs.stat(path.join(docsPath, file));
|
|
return {
|
|
name: file,
|
|
size: stats.size,
|
|
sizeMB: (stats.size / 1024 / 1024).toFixed(2),
|
|
created: stats.birthtime,
|
|
modified: stats.mtime
|
|
};
|
|
})
|
|
);
|
|
|
|
res.json({
|
|
count: pdfFiles.length,
|
|
files: fileDetails
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Error handling middleware
|
|
app.use((err, req, res, next) => {
|
|
console.error(`[${new Date().toISOString()}] Error:`, err);
|
|
res.status(500).json({
|
|
error: err.message || 'Internal server error',
|
|
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined
|
|
});
|
|
});
|
|
|
|
app.listen(PORT, '0.0.0.0', () => {
|
|
console.log(`========================================`);
|
|
console.log(`VitePress API Server`);
|
|
console.log(`========================================`);
|
|
console.log(`API Server running on port: ${PORT}`);
|
|
console.log(`VitePress Server: http://localhost:${process.env.VITEPRESS_PORT || 3000}`);
|
|
console.log(`PDF output directory: ${process.env.DOCS_PATH || '/app/docs'}`);
|
|
console.log(`========================================`);
|
|
console.log(`Available API endpoints:`);
|
|
console.log(` GET /health - Health check`);
|
|
console.log(` GET /export-pdf - Export PDF`);
|
|
console.log(` GET /pdf-files - List all PDF files`);
|
|
console.log(`========================================`);
|
|
});
|