UNPKG

@maxlkatze/cms

Version:

A git based Nuxt Module CMS - zero effort, zero cost

93 lines (92 loc) 3.48 kB
import { ref, onMounted } from "vue"; export function useGitHubNews() { const newsArticles = ref([]); const isLoading = ref(false); const error = ref(null); const baseUrl = `https://api.github.com/repos/maxlkatze/katzen-core/contents`; const newsPath = "content/news"; const parseFrontmatter = (content) => { const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/; const match = content.match(frontmatterRegex); if (!match) { return { frontmatter: {}, body: content }; } const [, frontmatterStr, body] = match; const frontmatter = {}; frontmatterStr.split("\n").forEach((line) => { const [key, ...valueParts] = line.split(":"); if (key && valueParts.length) { let value = valueParts.join(":").trim(); if (value.startsWith("[") && value.endsWith("]")) { value = value.slice(1, -1); frontmatter[key.trim()] = value.split(",").map((v) => v.trim().replace(/"/g, "").replace(/'/g, "")); } else { frontmatter[key.trim()] = value.replace(/"/g, "").replace(/'/g, ""); } } }); return { frontmatter, body: body.trim() }; }; const fetchFile = async (path) => { try { const response = await fetch(`${baseUrl}/${path}?ref=master`); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || "Failed to fetch file"); } const data = await response.json(); const content = atob(data.content); const { frontmatter, body } = parseFrontmatter(content); const id = typeof frontmatter.id === "string" ? frontmatter.id : data.sha.substring(0, 8); const title = typeof frontmatter.title === "string" ? frontmatter.title : "Untitled"; const date = typeof frontmatter.date === "string" ? frontmatter.date : (/* @__PURE__ */ new Date()).toISOString().split("T")[0]; const author = typeof frontmatter.author === "string" ? frontmatter.author : "Unknown"; const tags = Array.isArray(frontmatter.tags) ? frontmatter.tags : []; return { id, title, content: body, date, author, tags }; } catch (err) { console.error(`Error fetching file ${path}:`, err); return null; } }; const fetchNewsArticles = async () => { isLoading.value = true; error.value = null; try { const response = await fetch(`${baseUrl}/${newsPath}?ref=master`); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || "Failed to fetch news directory"); } const data = await response.json(); const markdownFiles = data.filter( (file) => file.type === "file" && file.name.endsWith(".md") ); const articlesPromises = markdownFiles.map( (file) => fetchFile(`${newsPath}/${file.name}`) ); const articles = await Promise.all(articlesPromises); newsArticles.value = articles.filter((article) => article !== null).sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); } catch (err) { console.error("Error fetching news articles:", err); error.value = err instanceof Error ? err.message : "Unknown error"; } finally { isLoading.value = false; } }; onMounted(async () => { await fetchNewsArticles(); }); return { newsArticles, isLoading, error, refreshNews: fetchNewsArticles }; }