import fs from "node:fs/promises"; import path from "node:path"; import matter from "gray-matter"; export type BlogDetail = { slug: string; title: string; category: string; date: string; readTime: string; author: string; excerpt: string; coverImage: string; markdown: string; lang: "tr" | "en"; }; const BLOG_CONTENT_DIR = path.join(process.cwd(), "content", "blog"); function toSafeString(value: unknown, fallback: string) { if (typeof value !== "string") return fallback; const trimmed = value.trim(); return trimmed || fallback; } function normalizeSlug(fileName: string) { return fileName.replace(/\.md$/i, ""); } function mapMarkdownToBlogDetail(fileName: string, raw: string): BlogDetail { const parsed = matter(raw); const slug = normalizeSlug(fileName); return { slug, title: toSafeString(parsed.data.title, slug), category: toSafeString(parsed.data.category, "General"), date: toSafeString(parsed.data.date, ""), readTime: toSafeString(parsed.data.readTime, ""), author: toSafeString(parsed.data.author, "Poyraz Avsever"), excerpt: toSafeString(parsed.data.excerpt, ""), coverImage: toSafeString(parsed.data.coverImage, "/news/design.svg"), markdown: parsed.content.trim(), lang: toSafeString(parsed.data.lang, "tr") as "tr" | "en", }; } export async function listBlogDetails(locale?: string): Promise { let files: string[] = []; try { files = await fs.readdir(BLOG_CONTENT_DIR); } catch { return []; } const markdownFiles = files.filter((fileName) => fileName.endsWith(".md")); const posts = await Promise.all( markdownFiles.map(async (fileName) => { const targetPath = path.join(BLOG_CONTENT_DIR, fileName); const raw = await fs.readFile(targetPath, "utf8"); return mapMarkdownToBlogDetail(fileName, raw); }), ); return posts .filter((post) => !locale || post.lang === locale) .sort((a, b) => a.slug.localeCompare(b.slug)); } export async function getBlogTranslations(post: BlogDetail) { const posts = await listBlogDetails(); return posts.filter( (candidate) => candidate.coverImage === post.coverImage && candidate.category.toLocaleLowerCase() === post.category.toLocaleLowerCase(), ); } export async function getBlogDetailBySlug(slug: string): Promise { const safeSlug = slug.trim().toLowerCase(); if (!safeSlug) return null; const targetPath = path.join(BLOG_CONTENT_DIR, `${safeSlug}.md`); try { const raw = await fs.readFile(targetPath, "utf8"); return mapMarkdownToBlogDetail(`${safeSlug}.md`, raw); } catch { return null; } }