added supabase

This commit is contained in:
Austin
2026-02-20 09:12:47 -06:00
parent ecbc399ec4
commit b54ad064ff
54 changed files with 3162 additions and 445 deletions
-162
View File
@@ -1,162 +0,0 @@
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';
import { PostData, PostMetadata } from '@/types';
// Make sure this is only used on the server side
const postsDirectory = path.join(process.cwd(), 'data/posts');
export function getSortedPostsData(): PostMetadata[] {
// Ensure we only run this on the server
if (typeof window === 'undefined') {
try {
// Get file names under /posts
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames
.filter(fileName => fileName.endsWith('.md')) // Only process .md files
.map((fileName) => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, '');
// Skip if id is empty or undefined
if (!id || id === 'undefined') {
console.warn(`Skipping invalid filename: ${fileName}`);
return null;
}
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
title: matterResult.data.title || '',
date: matterResult.data.date || '',
excerpt: matterResult.data.excerpt || '',
author: matterResult.data.author || '',
tags: matterResult.data.tags || [],
coverImage: matterResult.data.coverImage || undefined,
} as PostMetadata;
})
.filter((post): post is PostMetadata => post !== null); // Filter out null values
// Sort posts by date
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1;
} else {
return -1;
}
});
} catch (error) {
console.error('Error reading posts directory:', error);
return [];
}
}
// Return empty array if running on client side
return [];
}
export function getAllPostIds() {
// Ensure we only run this on the server
if (typeof window === 'undefined') {
try {
const fileNames = fs.readdirSync(postsDirectory);
return fileNames
.filter(fileName => fileName.endsWith('.md'))
.map((fileName) => {
const id = fileName.replace(/\.md$/, '');
if (!id || id === 'undefined') {
return null;
}
return {
params: {
id,
},
};
})
.filter((item): item is { params: { id: string } } => item !== null);
} catch (error) {
console.error('Error reading posts directory:', error);
return [];
}
}
// Return empty array if running on client side
return [];
}
export async function getPostData(id: string): Promise<PostData> {
// Ensure we only run this on the server
if (typeof window === 'undefined') {
try {
// Validate id
if (!id || id === 'undefined') {
throw new Error(`Invalid post id: ${id}`);
}
const fullPath = path.join(postsDirectory, `${id}.md`);
// Check if file exists
if (!fs.existsSync(fullPath)) {
throw new Error(`Post file not found: ${fullPath}`);
}
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents);
// Use remark to convert markdown into HTML string
const processedContent = await remark()
.use(html, { sanitize: false })
.process(matterResult.content);
const contentHtml = processedContent.toString();
// Combine the data with the id and contentHtml
return {
id,
content: contentHtml,
title: matterResult.data.title || '',
date: matterResult.data.date || '',
excerpt: matterResult.data.excerpt || '',
author: matterResult.data.author || '',
tags: matterResult.data.tags || [],
coverImage: matterResult.data.coverImage || undefined,
};
} catch (error) {
console.error(`Error loading post ${id}:`, error);
throw error;
}
}
// Return empty object if running on client side (should never happen in practice)
return {
id: '',
content: '',
title: '',
date: '',
excerpt: '',
author: '',
tags: [],
};
}
export function getPostsByTag(tag: string): PostMetadata[] {
const allPosts = getSortedPostsData();
return allPosts.filter(post => post.tags.includes(tag));
}
export function getPostsByAuthor(author: string): PostMetadata[] {
const allPosts = getSortedPostsData();
return allPosts.filter(post => post.author.includes(author));
}
+125
View File
@@ -0,0 +1,125 @@
import { createClient } from "@/utils/supabase/server";
import { PostData, PostMetadata } from "@/types";
export async function getSortedPostsData(): Promise<PostMetadata[]> {
const supabase = await createClient();
const { data, error } = await supabase
.from("posts")
.select("id, title, date, excerpt, author, tags, cover_image")
.eq("published", true)
.order("date", { ascending: false });
if (error) {
console.error("Error fetching posts:", error);
return [];
}
return (data || []).map((post) => ({
id: post.id,
title: post.title,
date: post.date,
excerpt: post.excerpt,
author: post.author,
tags: post.tags || [],
coverImage: post.cover_image || undefined,
}));
}
export async function getAllPostIds(): Promise<{ params: { id: string } }[]> {
const supabase = await createClient();
const { data, error } = await supabase
.from("posts")
.select("id")
.eq("published", true);
if (error) {
console.error("Error fetching post IDs:", error);
return [];
}
return (data || []).map((post) => ({
params: { id: post.id },
}));
}
export async function getPostData(id: string): Promise<PostData> {
const supabase = await createClient();
const { data, error } = await supabase
.from("posts")
.select("id, title, date, excerpt, content_html, author, tags, cover_image")
.eq("id", id)
.single();
if (error || !data) {
console.error(`Error fetching post ${id}:`, error);
throw new Error(`Post not found: ${id}`);
}
return {
id: data.id,
title: data.title,
date: data.date,
excerpt: data.excerpt,
content: data.content_html,
author: data.author,
tags: data.tags || [],
coverImage: data.cover_image || undefined,
};
}
export async function getPostsByTag(tag: string): Promise<PostMetadata[]> {
const supabase = await createClient();
const { data, error } = await supabase
.from("posts")
.select("id, title, date, excerpt, author, tags, cover_image")
.eq("published", true)
.contains("tags", [tag])
.order("date", { ascending: false });
if (error) {
console.error("Error fetching posts by tag:", error);
return [];
}
return (data || []).map((post) => ({
id: post.id,
title: post.title,
date: post.date,
excerpt: post.excerpt,
author: post.author,
tags: post.tags || [],
coverImage: post.cover_image || undefined,
}));
}
export async function getPostsByAuthor(
author: string
): Promise<PostMetadata[]> {
const supabase = await createClient();
const { data, error } = await supabase
.from("posts")
.select("id, title, date, excerpt, author, tags, cover_image")
.eq("published", true)
.eq("author", author)
.order("date", { ascending: false });
if (error) {
console.error("Error fetching posts by author:", error);
return [];
}
return (data || []).map((post) => ({
id: post.id,
title: post.title,
date: post.date,
excerpt: post.excerpt,
author: post.author,
tags: post.tags || [],
coverImage: post.cover_image || undefined,
}));
}