This commit is contained in:
2025-11-28 17:20:08 +08:00
parent 0b0650f374
commit f1d413afae
6 changed files with 49 additions and 403 deletions

View File

@@ -70,34 +70,8 @@ export async function getAllAuthors(): Promise<CollectionEntry<'authors'>[]> {
return getCollectionSafe('authors')
}
export const POSTS_API_URL = 'https://notion-api.nvme0n1p.dev/v2/posts'
export async function getAllPosts(): Promise<CollectionEntry<'blog'>[]> {
const fallback = async () => {
const posts = await getCollectionSafe('blog')
return posts
.filter((post) => !post.data.draft && !isSubpost(post.id))
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
.map((post) => ({
...post,
data: {
...post.data,
banner: post.data.banner ?? post.data.image,
authors: [DEFAULT_AUTHOR_ID],
},
}))
}
try {
const res = await fetch(POSTS_API_URL)
if (!res.ok) throw new Error(`Failed to fetch posts: ${res.status}`)
const payload = (await res.json()) as { posts?: NotionPost[] }
const posts = (payload.posts ?? []).filter(
(post) => post.Published ?? true,
)
const normalized = posts.map((post) => {
const dateString =
export function normalizePost(post: NotionPost): CollectionEntry<'blog'> {
const dateString =
post['Published Date'] ?? post.created_time ?? new Date().toISOString()
const date = new Date(dateString)
const id = post.slug || post.id
@@ -114,37 +88,39 @@ export async function getAllPosts(): Promise<CollectionEntry<'blog'>[]> {
tags: Array.isArray(post.Tags) ? post.Tags : [],
draft: !(post.Published ?? true),
authors: [DEFAULT_AUTHOR_ID],
banner,
image,
},
body: '',
}
})
}
export async function getAllPosts(): Promise<CollectionEntry<'blog'>[]> {
try {
const res = await fetch("https://notion-api.nvme0n1p.dev/v2/posts")
if (!res.ok) throw new Error(`Failed to fetch posts: ${res.status}`)
const payload = (await res.json()) as { posts?: NotionPost[] }
const posts = (payload.posts ?? []).filter(
(post) => post.Published ?? true,
)
const normalized = posts.map(normalizePost)
return normalized
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
.filter((post) => !isSubpost(post.id)) as unknown as CollectionEntry<'blog'>[]
} catch (error) {
console.error('getAllPosts remote fetch failed, using fallback:', error)
return fallback()
return []
}
}
export async function getAllPostsAndSubposts(): Promise<
CollectionEntry<'blog'>[]
> {
// 远程源不区分子文章,直接沿用 getAllPosts 结果
return getAllPosts()
}
export async function getAllProjects(): Promise<CollectionEntry<'projects'>[]> {
const projects = await getCollectionSafe('projects')
return projects.sort((a, b) => {
const dateA = a.data.startDate?.getTime() || 0
const dateB = b.data.startDate?.getTime() || 0
return dateB - dateA
})
}
export async function getAllTags(): Promise<Map<string, number>> {
const posts = await getAllPosts()
@@ -163,41 +139,6 @@ export async function getAdjacentPosts(currentId: string): Promise<{
}> {
const allPosts = await getAllPosts()
if (isSubpost(currentId)) {
const parentId = getParentId(currentId)
const allPosts = await getAllPosts()
const parent = allPosts.find((post) => post.id === parentId) || null
const posts = await getCollectionSafe('blog')
const subposts = posts
.filter(
(post) =>
isSubpost(post.id) &&
getParentId(post.id) === parentId &&
!post.data.draft,
)
.sort((a, b) => {
const dateDiff = a.data.date.valueOf() - b.data.date.valueOf()
if (dateDiff !== 0) return dateDiff
const orderA = a.data.order ?? 0
const orderB = b.data.order ?? 0
return orderA - orderB
})
const currentIndex = subposts.findIndex((post) => post.id === currentId)
if (currentIndex === -1) {
return { newer: null, older: null, parent }
}
return {
newer:
currentIndex < subposts.length - 1 ? subposts[currentIndex + 1] : null,
older: currentIndex > 0 ? subposts[currentIndex - 1] : null,
parent,
}
}
const parentPosts = allPosts.filter((post) => !isSubpost(post.id))
const currentIndex = parentPosts.findIndex((post) => post.id === currentId)
@@ -287,15 +228,13 @@ export function groupPostsByYear(
}
export async function hasSubposts(postId: string): Promise<boolean> {
const subposts = await getSubpostsForParent(postId)
return subposts.length > 0
return false
}
export function isSubpost(postId: string): boolean {
return postId.includes('/')
return false
}
export const FRIENDS_API_URL = 'https://notion-api.nvme0n1p.dev/v2/links'
export async function fetchRemotePost(
slug: string,
): Promise<NotionPost | null> {
@@ -314,16 +253,11 @@ export async function fetchRemotePostContent(
slug: string,
): Promise<RemotePostPayload | null> {
try {
const res = await fetch(`${POSTS_API_URL}/${encodeURI(slug)}`)
const res = await fetch(`https://notion-api.nvme0n1p.dev/v2/posts/${encodeURI(slug)}`)
if (!res.ok) throw new Error(`Failed to fetch post content: ${res.status}`)
const data = (await res.json()) as Partial<RemotePostPayload>
if (!data.post || !data.blockMap) return null
const post = data.post as any
if (post?.banner && !post?.image) {
post.image = post.banner
}
data.post = normalizePost(data.post)
return data as RemotePostPayload
} catch (error) {
console.error(`fetchRemotePostContent error for slug "${slug}":`, error)
@@ -332,28 +266,24 @@ export async function fetchRemotePostContent(
}
export async function getFriendLinks(): Promise<LinkEntry[]> {
const fallback: LinkEntry[] = []
try {
const res = await fetch(FRIENDS_API_URL)
const res = await fetch("https://notion-api.nvme0n1p.dev/v2/links")
if (!res.ok) throw new Error(`Failed to fetch links: ${res.status}`)
const data = (await res.json()) as LinkEntry[]
if (!Array.isArray(data)) return fallback
if (!Array.isArray(data)) throw new Error('Invalid links data format')
return data
} catch (error) {
console.error('getFriendLinks error:', error)
return fallback
return []
}
}
export async function getParentPost(
subpostId: string,
): Promise<CollectionEntry<'blog'> | null> {
if (!isSubpost(subpostId)) {
return null
}
const parentId = getParentId(subpostId)
const allPosts = await getAllPosts()