101 lines
2.8 KiB
JavaScript
101 lines
2.8 KiB
JavaScript
import { promises as fs } from 'fs'
|
|
import { getCurrentSeasonSlug, validateSeasonSlug } from '../utils/spielplan-data.js'
|
|
|
|
function normalizeSeasonFilename(season) {
|
|
return `mannschaften_${season}.csv`
|
|
}
|
|
|
|
function isAllowedFilename(filename) {
|
|
return filename === 'mannschaften.csv' || /^mannschaften_\d{2}--\d{2}\.csv$/.test(String(filename || ''))
|
|
}
|
|
|
|
function buildCsvCandidates(cwd, filename) {
|
|
const safeFilename = String(filename || '').trim()
|
|
if (!isAllowedFilename(safeFilename)) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'Ungueltiger Dateiname fuer Mannschaften'
|
|
})
|
|
}
|
|
|
|
return [
|
|
`${cwd}/server/data/public-data/${safeFilename}`,
|
|
`${cwd}/../server/data/public-data/${safeFilename}`,
|
|
`${cwd}/.output/server/data/${safeFilename}`,
|
|
`${cwd}/server/data/${safeFilename}`,
|
|
`${cwd}/.output/public/data/${safeFilename}`,
|
|
`${cwd}/public/data/${safeFilename}`,
|
|
`${cwd}/../.output/public/data/${safeFilename}`,
|
|
`${cwd}/../public/data/${safeFilename}`
|
|
]
|
|
}
|
|
|
|
async function exists(p) {
|
|
try {
|
|
await fs.access(p)
|
|
return true
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
try {
|
|
const cwd = process.cwd()
|
|
const query = getQuery(event)
|
|
const requestedSeason = query.season ? String(query.season).trim() : ''
|
|
|
|
if (requestedSeason && !validateSeasonSlug(requestedSeason)) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'Ungueltiger Saison-Slug'
|
|
})
|
|
}
|
|
|
|
const defaultSeason = getCurrentSeasonSlug()
|
|
const candidateFileNames = requestedSeason
|
|
? [normalizeSeasonFilename(requestedSeason), 'mannschaften.csv']
|
|
: [normalizeSeasonFilename(defaultSeason), 'mannschaften.csv']
|
|
|
|
// Prefer CMS write target first (server/data/public-data),
|
|
// then legacy locations.
|
|
const candidates = []
|
|
for (const filename of candidateFileNames) {
|
|
candidates.push(...buildCsvCandidates(cwd, filename))
|
|
}
|
|
|
|
let csvPath = null
|
|
for (const p of candidates) {
|
|
|
|
if (await exists(p)) {
|
|
csvPath = p
|
|
break
|
|
}
|
|
}
|
|
|
|
if (!csvPath) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
statusMessage: 'Mannschaften-Datei nicht gefunden'
|
|
})
|
|
}
|
|
|
|
const csv = await fs.readFile(csvPath, 'utf-8')
|
|
|
|
setHeader(event, 'Content-Type', 'text/csv; charset=utf-8')
|
|
setHeader(event, 'Cache-Control', 'no-cache, no-store, must-revalidate')
|
|
setHeader(event, 'Pragma', 'no-cache')
|
|
setHeader(event, 'Expires', '0')
|
|
|
|
return csv
|
|
} catch (error) {
|
|
if (error?.statusCode) throw error
|
|
console.error('Fehler beim Laden der Mannschaften:', error)
|
|
throw createError({
|
|
statusCode: 500,
|
|
statusMessage: 'Fehler beim Laden der Mannschaften'
|
|
})
|
|
}
|
|
})
|
|
|