85 lines
2.1 KiB
TypeScript
85 lines
2.1 KiB
TypeScript
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<Post> => {
|
|
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<Array<Post>> {
|
|
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<Post>;
|
|
|
|
/** */
|
|
export const fetchPosts = async (): Promise<Array<Post>> => {
|
|
if (!_posts) {
|
|
_posts = await load();
|
|
}
|
|
|
|
return _posts;
|
|
};
|
|
|
|
/** */
|
|
export const findPostsBySlugs = async (slugs: Array<string>): Promise<Array<Post>> => {
|
|
if (!Array.isArray(slugs)) return [];
|
|
|
|
const posts = await fetchPosts();
|
|
|
|
return slugs.reduce(function (r: Array<Post>, slug: string) {
|
|
posts.some(function (post: Post) {
|
|
return slug === post.slug && r.push(post);
|
|
});
|
|
return r;
|
|
}, []);
|
|
};
|
|
|
|
/** */
|
|
export const findPostsByIds = async (ids: Array<string>): Promise<Array<Post>> => {
|
|
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<Array<Post>> => {
|
|
const _count = count || 4;
|
|
const posts = await fetchPosts();
|
|
|
|
return posts ? posts.slice(_count * -1) : [];
|
|
};
|