corrad-af-2024/server/api/docs/[...slug].get.js

65 lines
1.7 KiB
JavaScript

import fs from 'fs'
import path from 'path'
export default defineEventHandler(async (event) => {
try {
const slug = getRouterParam(event, 'slug')
if (!slug) {
throw createError({
statusCode: 400,
statusMessage: 'File path is required'
})
}
// Clean the slug to prevent directory traversal
const cleanSlug = slug.replace(/\.\./g, '').replace(/\/+/g, '/')
const filename = cleanSlug.endsWith('.md') || cleanSlug.endsWith('.json')
? cleanSlug
: `${cleanSlug}.md`
// Construct file path
const filePath = path.join(process.cwd(), 'docs', filename)
// Check if file exists
if (!fs.existsSync(filePath)) {
throw createError({
statusCode: 404,
statusMessage: 'File not found'
})
}
// Read file content
const content = fs.readFileSync(filePath, 'utf-8')
// Set appropriate content type
if (filename.endsWith('.json')) {
setHeader(event, 'Content-Type', 'application/json')
} else if (filename.endsWith('.md')) {
setHeader(event, 'Content-Type', 'text/markdown; charset=utf-8')
} else {
setHeader(event, 'Content-Type', 'text/plain; charset=utf-8')
}
// Set cache headers
setHeader(event, 'Cache-Control', 'public, max-age=300')
return content
} catch (error) {
console.error('Error serving docs file:', error)
// If it's already a createError, re-throw it
if (error.statusCode) {
throw error
}
throw createError({
statusCode: 500,
statusMessage: 'Failed to serve file',
data: {
error: error.message
}
})
}
})