feat: add cv
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import type { H3Event } from 'h3'
|
||||
|
||||
interface SelectValue {
|
||||
value: string
|
||||
}
|
||||
|
||||
interface FileValue {
|
||||
url: string
|
||||
visible_name: string
|
||||
}
|
||||
|
||||
export interface CvRow {
|
||||
id: number
|
||||
From: string | null
|
||||
To: string | null
|
||||
Type: SelectValue | null
|
||||
Institution: string | null
|
||||
Area: string | null
|
||||
area_german?: string | null
|
||||
Place: SelectValue | null
|
||||
Grade: string | null
|
||||
file?: FileValue[] | null
|
||||
urls?: string | null
|
||||
}
|
||||
|
||||
export function cvTable(event: H3Event): string {
|
||||
const { baserowCvTableId } = useRuntimeConfig(event)
|
||||
if (!baserowCvTableId) {
|
||||
throw createError({ statusCode: 500, statusMessage: 'NUXT_BASEROW_CV_TABLE_ID is not set' })
|
||||
}
|
||||
return baserowCvTableId
|
||||
}
|
||||
|
||||
/** Baserow hands out file URLs with its internal protocol (http); serve them from the configured Baserow URL instead */
|
||||
function fileUrl(url: string, baserowUrl: string): string {
|
||||
const { pathname } = new URL(url)
|
||||
return new URL(pathname, baserowUrl).href
|
||||
}
|
||||
|
||||
function toCvLink(line: string): CvLink | null {
|
||||
// "https://…", or "Label https://…" for custom link text
|
||||
const match = line.match(/^(.*?)[\s:|–-]*(https?:\/\/\S+)$/)
|
||||
if (!match) return null
|
||||
let url: URL
|
||||
try {
|
||||
url = new URL(match[2]!)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
const path = url.pathname.replace(/\/+$/, '')
|
||||
const kind = url.hostname === 'github.com' ? 'github' : 'web'
|
||||
const fallback = kind === 'github' ? path.slice(1) : url.hostname + path
|
||||
return { label: match[1]!.trim() || fallback, url: url.href, kind }
|
||||
}
|
||||
|
||||
/** One URL per line; a blank line starts a new group */
|
||||
function toCvLinks(text: string | null | undefined): CvLink[][] {
|
||||
return (text ?? '')
|
||||
.split(/\n\s*\n/)
|
||||
.map(block => block.split('\n').map(line => toCvLink(line.trim())).filter((link): link is CvLink => !!link))
|
||||
.filter(group => group.length)
|
||||
}
|
||||
|
||||
export function toCvEntry(row: CvRow, baserowUrl: string): CvEntry | null {
|
||||
if (!row.From) return null
|
||||
return {
|
||||
id: row.id,
|
||||
from: row.From,
|
||||
to: row.To || null,
|
||||
type: (row.Type?.value as CvType | undefined) ?? null,
|
||||
institution: (row.Institution ?? '').trim(),
|
||||
area: (row.Area ?? '').trim(),
|
||||
areaGerman: (row.area_german ?? '').trim(),
|
||||
place: row.Place?.value ?? null,
|
||||
grade: row.Grade ?? null,
|
||||
files: (row.file ?? []).map(file => ({ name: file.visible_name, url: fileUrl(file.url, baserowUrl) })),
|
||||
links: toCvLinks(row.urls)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user