mirror of
https://github.com/supabase/supabase.git
synced 2026-10-12 12:55:06 +03:00
This PR removes all CMS code from the `www` app. This includes fetching of blog posts, API routes for proxying blog posts and types. All functionality should remain the same (and the number of blog posts should be the same). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Removed CMS integration, APIs, preview/draft/revalidate endpoints, related env vars and dependency; switched to static markdown-only blog pipeline. * **Refactor** * Simplified image and author resolution, tightened component props to static post shapes, and migrated imports to path aliases. * **Documentation** * Deleted CMS integration docs and rich-text conversion helpers. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
|
|
import { getSortedPosts } from '@/lib/posts'
|
|
|
|
export const revalidate = 30
|
|
|
|
// Cache for combined posts to avoid re-fetching on every request
|
|
let cachedPosts: any[] | null = null
|
|
let cacheTimestamp = 0
|
|
const CACHE_TTL = 30 * 1000 // 30 seconds
|
|
|
|
async function getCombinedPosts() {
|
|
const now = Date.now()
|
|
|
|
// Return cached posts if still valid
|
|
if (cachedPosts && now - cacheTimestamp < CACHE_TTL) {
|
|
return cachedPosts
|
|
}
|
|
|
|
// Get static blog posts
|
|
const staticPosts = getSortedPosts({ directory: '_blog' })
|
|
|
|
// Combine and sort by date
|
|
const allPosts = [...staticPosts].sort((a: any, b: any) => {
|
|
const dateA = new Date(a.date || a.formattedDate).getTime()
|
|
const dateB = new Date(b.date || b.formattedDate).getTime()
|
|
return dateB - dateA
|
|
})
|
|
|
|
// Update cache
|
|
cachedPosts = allPosts
|
|
cacheTimestamp = now
|
|
|
|
return allPosts
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const { searchParams } = new URL(request.url)
|
|
const offset = parseInt(searchParams.get('offset') || '0', 10)
|
|
const limit = parseInt(searchParams.get('limit') || '25', 10)
|
|
const category = searchParams.get('category')
|
|
const search = searchParams.get('q')
|
|
|
|
let posts = await getCombinedPosts()
|
|
|
|
// Apply category filter
|
|
if (category && category !== 'all') {
|
|
posts = posts.filter((post: any) => post.categories?.includes(category))
|
|
}
|
|
|
|
// Apply search filter
|
|
if (search) {
|
|
const searchLower = search.toLowerCase()
|
|
posts = posts.filter((post: any) => {
|
|
return (
|
|
post.tags?.join(' ').replaceAll('-', ' ').includes(searchLower) ||
|
|
post.title?.toLowerCase().includes(searchLower) ||
|
|
post.author?.toLowerCase().includes(searchLower)
|
|
)
|
|
})
|
|
}
|
|
|
|
const total = posts.length
|
|
const paginatedPosts = posts.slice(offset, offset + limit)
|
|
const hasMore = offset + limit < total
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
posts: paginatedPosts,
|
|
total,
|
|
offset,
|
|
limit,
|
|
hasMore,
|
|
})
|
|
} catch (error) {
|
|
console.error('[blog-posts] Error:', error)
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: 'Internal server error',
|
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
})
|
|
}
|
|
}
|