Files
website/server/utils/review.ts
T
2026-09-23 11:44:36 +02:00

59 lines
1.6 KiB
TypeScript

import type { H3Event } from 'h3'
export interface ReviewRow {
id: number
title: string | null
date: string | null
author_or_director: string | null
review: string | null
medium: SelectOption | null
}
interface SelectOption {
id: number
value: string
}
interface Field {
name: string
select_options?: SelectOption[]
}
const OPTION_CACHE_MS = 10 * 60_000
let mediumOptions: { ids: Partial<Record<Medium, number>>, fetchedAt: number } | null = null
function toMedium(value: string | undefined): Medium | null {
return MEDIUM_KEYS.find(medium => MEDIUMS[medium].label === value) ?? null
}
export function toReview(row: ReviewRow): Review {
return {
id: row.id,
date: row.date ?? '',
title: (row.title ?? '').trim(),
author: row.author_or_director?.trim() || null,
text: (row.review ?? '').replace(/&nbsp;/g, ' ').trim(),
medium: toMedium(row.medium?.value)
}
}
export async function mediumOptionId(event: H3Event, medium: Medium): Promise<number> {
if (!mediumOptions || Date.now() - mediumOptions.fetchedAt > OPTION_CACHE_MS) {
const fields = await listFields<Field>(event, 'reviews')
const options = fields.find(field => field.name === 'medium')?.select_options ?? []
const ids: Partial<Record<Medium, number>> = {}
for (const option of options) {
const key = toMedium(option.value)
if (key) ids[key] = option.id
}
mediumOptions = { ids, fetchedAt: Date.now() }
}
const id = mediumOptions.ids[medium]
if (!id) {
throw createError({ statusCode: 500, statusMessage: `The medium field has no "${MEDIUMS[medium].label}" option` })
}
return id
}