Files
kgva/cms/core/api/src/routes/profile.js
T

57 lines
2.2 KiB
JavaScript

import { Hono } from 'hono';
import { readFile, writeFile, mkdir, stat } from 'node:fs/promises';
import path from 'node:path';
import matter from 'gray-matter';
import { buildSite } from '../hugo.js';
// Profile als Hugo-Data-Datei (data/authors.json) + öffentliche Autor-Seite
// (content/authors/<slug>.md), gerendert von layouts/authors/single.html.
const SITE_DIR = process.env.SITE_DIR || '/site';
const FILE = path.join(SITE_DIR, 'data', 'authors.json');
const AUTHORS_DIR = path.join(SITE_DIR, 'content', 'authors');
async function readAll() {
try { return JSON.parse(await readFile(FILE, 'utf8')); } catch { return {}; }
}
// Muss zu Hugos `urlize` passen (Byline-Link).
function slugify(s) {
return String(s || '').toLowerCase().trim().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
}
async function exists(p) { try { await stat(p); return true; } catch { return false; } }
const profile = new Hono();
profile.get('/', async (c) => {
const email = c.get('user')?.email || 'default';
const all = await readAll();
return c.json({ email, name: '', bio: '', avatar: '', ...(all[email] || {}) });
});
profile.put('/', async (c) => {
const email = c.get('user')?.email || 'default';
const { name, bio, avatar } = await c.req.json();
const slug = slugify(name);
const all = await readAll();
all[email] = { name: name || '', bio: bio || '', avatar: avatar || '', slug };
await mkdir(path.dirname(FILE), { recursive: true });
await writeFile(FILE, JSON.stringify(all, null, 2) + '\n', 'utf8');
// Öffentliche Autor-Seite schreiben (nur mit Name).
if (slug) {
await mkdir(AUTHORS_DIR, { recursive: true });
const idx = path.join(AUTHORS_DIR, '_index.md');
if (!(await exists(idx))) {
await writeFile(idx, matter.stringify('', { title: 'Autor:innen' }), 'utf8');
}
const page = matter.stringify(bio || '', { title: name, avatar: avatar || '' });
await writeFile(path.join(AUTHORS_DIR, `${slug}.md`), page, 'utf8');
// Live bauen (koalesziert), damit die Seite + Byline-Links sofort wirken.
await buildSite({ dest: 'public', drafts: false }).catch((e) => console.error('[profile] build:', e?.message || e));
}
return c.json({ ok: true, slug });
});
export default profile;