65 lines
1.7 KiB
JavaScript
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
|
|
}
|
|
})
|
|
}
|
|
})
|