personal-website/lib/notion/content/blogPosts.ts
Filipe Medeiros fead4dccea
fix: blog post order
Signed-off-by: Filipe Medeiros <hello@filipesm.eu>
2023-12-03 12:25:56 +01:00

86 lines
2.6 KiB
TypeScript

import notion from '../client'
import { type PageWithProps } from '../types'
import { and, richTextFilter, statusFilter } from '../utils/filters'
import { sortProperty, sortTimestamp } from '../utils/sorts'
import { collectPaginatedAPI, isFullPage } from '@notionhq/client'
import { QueryDatabaseResponse } from '@notionhq/client/build/src/api-endpoints'
import { cache } from 'react'
export type BlogPost = PageWithProps<{
Status: 'status'
Slug: 'rich_text'
Description: 'rich_text'
PublishDate: 'date'
Topics: 'multi_select'
MetaDescription: 'rich_text'
MetaTwitterCard: 'select'
}>
export const databaseId = '0d40e441b70942f380c6b599d92018eb'
export const getFirstBlogPosts = cache(
async ({ published = true }: { published?: boolean } = {}) =>
notion.databases.query({
database_id: databaseId,
page_size: 10,
sorts: [
sortProperty('PublishDate', 'descending'),
sortTimestamp('last_edited_time', 'descending'),
],
filter: published
? and(
richTextFilter('Slug', 'is_not_empty', true),
statusFilter('Status', 'equals', 'Published'),
)
: undefined,
}) as Promise<
Omit<QueryDatabaseResponse, 'results'> & {
results: BlogPost[]
}
>,
)
export const getAllBlogPosts = cache(
async ({ published = true }: { published?: boolean } = {}) =>
collectPaginatedAPI(notion.databases.query, {
database_id: databaseId,
page_size: 100,
sorts: [
sortProperty('PublishDate', 'descending'),
sortTimestamp('created_time', 'descending'),
sortTimestamp('last_edited_time', 'descending'),
],
filter: published
? and(
richTextFilter('Slug', 'is_not_empty', true),
statusFilter('Status', 'equals', 'Published'),
)
: undefined,
}) as Promise<BlogPost[]>,
)
export const getBlogPostBySlug = cache(
async ({ slug, published = true }: { slug: string; published?: boolean }) => {
const publishedFilter = statusFilter('Status', 'equals', 'Published')
const slugFilter = richTextFilter('Slug', 'equals', slug)
const { results } = await (notion.databases.query({
database_id: databaseId,
filter: published ? and(publishedFilter, slugFilter) : slugFilter,
}) as Promise<
Omit<QueryDatabaseResponse, 'results'> & {
results: BlogPost[]
}
>)
if (results.length !== 1) return undefined
if (!isFullPage(results[0])) return undefined
if (results[0].properties.Slug.rich_text.length === 0) return undefined
return results[0]
},
)