84 lines
2.5 KiB
TypeScript
84 lines
2.5 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'
|
|
}>
|
|
|
|
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('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]
|
|
},
|
|
)
|