mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-10-27 01:36:25 -04:00
- Replace CommentFormContext/Provider with a plain `useCommentFormState` hook; the context abstraction was unused outside the file - Narrow auth-client exports to only `signIn`; `authClient` and `useSession` are no longer exported - Add `getPosts()` as a canonical sorted-posts helper and use it in `getFrontMatter` and `buildFeed`, removing the redundant sort in the latter - Drop JSON feed support from `createFeedHandler` since no JSON feed route exists - Rewrite `FrontMatter` as a `Pick` over the content-collections `Post` type to stay in sync automatically
80 lines
2.4 KiB
TypeScript
80 lines
2.4 KiB
TypeScript
import { allPosts } from "content-collections";
|
|
|
|
export type Post = (typeof allPosts)[number];
|
|
|
|
/** The subset of a post's fields used for listings, metadata and the OG image (everything except the body). */
|
|
export type FrontMatter = Pick<
|
|
Post,
|
|
| "slug"
|
|
| "permalink"
|
|
| "date"
|
|
| "title"
|
|
| "htmlTitle"
|
|
| "description"
|
|
| "tags"
|
|
| "image"
|
|
| "noComments"
|
|
>;
|
|
|
|
/** Path to directory with .mdx files, relative to project root. */
|
|
export const POSTS_DIR = "notes" as const;
|
|
|
|
/** Use generated content collections data to get all post slugs. */
|
|
export const getSlugs = (): string[] => {
|
|
return allPosts.map((post) => post.slug);
|
|
};
|
|
|
|
/** Returns the post for a given slug, or undefined if the slug does not exist. */
|
|
export const getPost = (slug: string): Post | undefined => {
|
|
return allPosts.find((post) => post.slug === slug);
|
|
};
|
|
|
|
/**
|
|
* Returns the post for a page slug in the "notes/<slug>" format used by the `page` and `comment` tables
|
|
* (e.g. "notes/dark-mode"), or undefined if it isn't an existing post.
|
|
*/
|
|
export const getPostByPageSlug = (pageSlug: string): Post | undefined => {
|
|
const prefix = `${POSTS_DIR}/`;
|
|
if (!pageSlug.startsWith(prefix)) return undefined;
|
|
return getPost(pageSlug.slice(prefix.length));
|
|
};
|
|
|
|
/** Returns ALL posts, sorted reverse chronologically. */
|
|
export const getPosts = (): Post[] =>
|
|
allPosts.toSorted(
|
|
(post1, post2) => new Date(post2.date).getTime() - new Date(post1.date).getTime(),
|
|
);
|
|
|
|
/**
|
|
* Returns the front matter of ALL posts, sorted reverse chronologically.
|
|
*/
|
|
export function getFrontMatter(): FrontMatter[];
|
|
/**
|
|
* Returns the front matter of a given slug, or undefined if the slug does not exist.
|
|
*/
|
|
export function getFrontMatter(slug: string): FrontMatter | undefined;
|
|
export function getFrontMatter(slug?: string): FrontMatter[] | FrontMatter | undefined {
|
|
const toFrontMatter = (post: Post): FrontMatter => ({
|
|
slug: post.slug,
|
|
permalink: post.permalink,
|
|
date: post.date,
|
|
title: post.title,
|
|
htmlTitle: post.htmlTitle,
|
|
description: post.description,
|
|
tags: post.tags,
|
|
image: post.image,
|
|
noComments: post.noComments,
|
|
});
|
|
|
|
if (typeof slug === "string") {
|
|
const matchedPost = allPosts.find((candidate) => candidate.slug === slug);
|
|
return matchedPost ? toFrontMatter(matchedPost) : undefined;
|
|
}
|
|
|
|
if (!slug) {
|
|
return getPosts().map(toFrontMatter);
|
|
}
|
|
|
|
throw new Error("getFrontMatter() called with invalid argument.");
|
|
}
|