summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/blog
diff options
context:
space:
mode:
authorMaze <167211895+mazeincoding@users.noreply.github.com>2026-01-31 00:20:04 +0100
committerGitHub <noreply@github.com>2026-01-31 00:20:04 +0100
commit7bf0984698e43b9aa2dd879f65951318ed410390 (patch)
treeccf2cd590a47d550152afc07129cb55c71a9ec35 /apps/web/src/lib/blog
parent0173db99448d1c4c6415dcf15272e17551b48b04 (diff)
downloadopencut-7bf0984698e43b9aa2dd879f65951318ed410390.tar.gz
codebase overhaul (#697)
Diffstat (limited to 'apps/web/src/lib/blog')
-rw-r--r--apps/web/src/lib/blog/query.ts72
1 files changed, 72 insertions, 0 deletions
diff --git a/apps/web/src/lib/blog/query.ts b/apps/web/src/lib/blog/query.ts
new file mode 100644
index 00000000..e6d68bb6
--- /dev/null
+++ b/apps/web/src/lib/blog/query.ts
@@ -0,0 +1,72 @@
+import type {
+ MarbleAuthorList,
+ MarbleCategoryList,
+ MarblePost,
+ MarblePostList,
+ MarbleTagList,
+} from "@/types/blog";
+import { unified } from "unified";
+import rehypeParse from "rehype-parse";
+import rehypeStringify from "rehype-stringify";
+import rehypeSlug from "rehype-slug";
+import rehypeAutolinkHeadings from "rehype-autolink-headings";
+import rehypeSanitize from "rehype-sanitize";
+
+const url =
+ process.env.NEXT_PUBLIC_MARBLE_API_URL ?? "https://api.marblecms.com";
+const key = process.env.MARBLE_WORKSPACE_KEY ?? "cmd4iw9mm0006l804kwqv0k46";
+
+async function fetchFromMarble<T>({
+ endpoint,
+}: {
+ endpoint: string;
+}): Promise<T> {
+ try {
+ const response = await fetch(`${url}/${key}/${endpoint}`);
+ if (!response.ok) {
+ throw new Error(
+ `Failed to fetch ${endpoint}: ${response.status} ${response.statusText}`,
+ );
+ }
+ return (await response.json()) as T;
+ } catch (error) {
+ console.error(`Error fetching ${endpoint}:`, error);
+ throw error;
+ }
+}
+
+export async function getPosts() {
+ return fetchFromMarble<MarblePostList>({ endpoint: "posts" });
+}
+
+export async function getTags() {
+ return fetchFromMarble<MarbleTagList>({ endpoint: "tags" });
+}
+
+export async function getSinglePost({ slug }: { slug: string }) {
+ return fetchFromMarble<MarblePost>({ endpoint: `posts/${slug}` });
+}
+
+export async function getCategories() {
+ return fetchFromMarble<MarbleCategoryList>({ endpoint: "categories" });
+}
+
+export async function getAuthors() {
+ return fetchFromMarble<MarbleAuthorList>({ endpoint: "authors" });
+}
+
+export async function processHtmlContent({
+ html,
+}: {
+ html: string;
+}): Promise<string> {
+ const processor = unified()
+ .use(rehypeSanitize)
+ .use(rehypeParse, { fragment: true })
+ .use(rehypeSlug)
+ .use(rehypeAutolinkHeadings, { behavior: "append" })
+ .use(rehypeStringify);
+
+ const file = await processor.process({ value: html, type: "html" });
+ return String(file);
+}