import { getCollection, getEntry } from 'astro:content'; import type { CollectionEntry } from 'astro:content'; import type { Post } from '~/types'; import { cleanSlug } from './permalinks'; const getNormalizedPost = async (post: CollectionEntry<'blog'>): Promise => { const { id, slug = '', data } = post; const { Content, injectedFrontmatter } = await post.render(); const { tags = [], category = 'default', author = 'Anonymous', publishDate = new Date(), ...rest } = data; return { id: id, slug: cleanSlug(slug.split('/').pop() ?? ''), publishDate: new Date(publishDate), category: cleanSlug(category), tags: tags.map((tag: string) => cleanSlug(tag)), author, ...rest, Content: Content, // or 'body' in case you consume from API readingTime: injectedFrontmatter.readingTime, }; }; const load = async function (): Promise> { const posts = await getCollection('blog'); const normalizedPosts = posts.map(async (post) => await getNormalizedPost(post)); const results = (await Promise.all(normalizedPosts)) .sort((a, b) => b.publishDate.valueOf() - a.publishDate.valueOf()) .filter((post) => !post.draft); return results; }; let _posts: Array; /** */ export const fetchPosts = async (): Promise> => { if (!_posts) { _posts = await load(); } return _posts; }; /** */ export const findPostsBySlugs = async (slugs: Array): Promise> => { if (!Array.isArray(slugs)) return []; const posts = await fetchPosts(); return slugs.reduce(function (r: Array, slug: string) { posts.some(function (post: Post) { return slug === post.slug && r.push(post); }); return r; }, []); }; /** */ export const findPostsByIds = async (ids: Array): Promise> => { if (!Array.isArray(ids)) return []; return await Promise.all( ids.map(async (id: never) => { const post = await getEntry('blog', id); return await getNormalizedPost(post); }) ); }; /** */ export const findLatestPosts = async ({ count }: { count?: number }): Promise> => { const _count = count || 4; const posts = await fetchPosts(); return posts ? posts.slice(_count * -1) : []; };