mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 17:48:30 -04:00
clean up note types
This commit is contained in:
parent
a2921d106e
commit
d718555001
@ -6,7 +6,7 @@ import NoteTitle from "../NoteTitle";
|
|||||||
import { DateIcon, TagIcon, EditIcon, ViewsIcon } from "../Icons";
|
import { DateIcon, TagIcon, EditIcon, ViewsIcon } from "../Icons";
|
||||||
import { styled } from "../../lib/styles/stitches.config";
|
import { styled } from "../../lib/styles/stitches.config";
|
||||||
import * as config from "../../lib/config";
|
import * as config from "../../lib/config";
|
||||||
import type { NoteType } from "../../types";
|
import type { NoteFrontMatter } from "../../types";
|
||||||
|
|
||||||
const Wrapper = styled("div", {
|
const Wrapper = styled("div", {
|
||||||
display: "inline-flex",
|
display: "inline-flex",
|
||||||
@ -56,7 +56,7 @@ const Tag = styled("span", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export type NoteMetaProps = Pick<NoteType["frontMatter"], "slug" | "date" | "title" | "htmlTitle" | "tags">;
|
export type NoteMetaProps = Pick<NoteFrontMatter, "slug" | "date" | "title" | "htmlTitle" | "tags">;
|
||||||
|
|
||||||
const NoteMeta = ({ slug, date, title, htmlTitle, tags = [] }: NoteMetaProps) => (
|
const NoteMeta = ({ slug, date, title, htmlTitle, tags = [] }: NoteMetaProps) => (
|
||||||
<>
|
<>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import NextLink from "next/link";
|
import NextLink from "next/link";
|
||||||
import { styled } from "../../lib/styles/stitches.config";
|
import { styled } from "../../lib/styles/stitches.config";
|
||||||
import type { ComponentProps } from "react";
|
import type { ComponentProps } from "react";
|
||||||
import type { NoteType } from "../../types";
|
import type { NoteFrontMatter } from "../../types";
|
||||||
|
|
||||||
const Title = styled("h1", {
|
const Title = styled("h1", {
|
||||||
margin: "0.3em 0 0.5em -1px", // misaligned left margin, super nitpicky
|
margin: "0.3em 0 0.5em -1px", // misaligned left margin, super nitpicky
|
||||||
@ -23,7 +23,7 @@ const Link = styled("a", {
|
|||||||
textDecoration: "none",
|
textDecoration: "none",
|
||||||
});
|
});
|
||||||
|
|
||||||
export type NoteTitleProps = Pick<NoteType["frontMatter"], "slug" | "htmlTitle"> & ComponentProps<typeof Title>;
|
export type NoteTitleProps = Pick<NoteFrontMatter, "slug" | "htmlTitle"> & ComponentProps<typeof Title>;
|
||||||
|
|
||||||
const NoteTitle = ({ slug, htmlTitle, ...rest }: NoteTitleProps) => (
|
const NoteTitle = ({ slug, htmlTitle, ...rest }: NoteTitleProps) => (
|
||||||
<Title {...rest}>
|
<Title {...rest}>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Link from "../Link";
|
import Link from "../Link";
|
||||||
import Time from "../Time";
|
import Time from "../Time";
|
||||||
import { styled } from "../../lib/styles/stitches.config";
|
import { styled } from "../../lib/styles/stitches.config";
|
||||||
import type { NoteType } from "../../types";
|
import type { NoteFrontMatter } from "../../types";
|
||||||
|
|
||||||
const Section = styled("section", {
|
const Section = styled("section", {
|
||||||
fontSize: "1.1em",
|
fontSize: "1.1em",
|
||||||
@ -54,13 +54,13 @@ const PostDate = styled(Time, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export type NotesListProps = {
|
export type NotesListProps = {
|
||||||
notesByYear: Record<string, NoteType["frontMatter"][]>;
|
notesByYear: Record<string, NoteFrontMatter[]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const NotesList = ({ notesByYear }: NotesListProps) => {
|
const NotesList = ({ notesByYear }: NotesListProps) => {
|
||||||
const sections = [];
|
const sections = [];
|
||||||
|
|
||||||
Object.entries(notesByYear).forEach(([year, notes]: [string, NoteType["frontMatter"][]]) => {
|
Object.entries(notesByYear).forEach(([year, notes]: [string, NoteFrontMatter[]]) => {
|
||||||
sections.push(
|
sections.push(
|
||||||
<Section key={year}>
|
<Section key={year}>
|
||||||
<Year>{year}</Year>
|
<Year>{year}</Year>
|
||||||
|
@ -3,7 +3,7 @@ import RelativeTime from "../RelativeTime";
|
|||||||
import { StarOcticon, ForkOcticon } from "../Icons";
|
import { StarOcticon, ForkOcticon } from "../Icons";
|
||||||
import { commafy } from "../../lib/helpers/format-number";
|
import { commafy } from "../../lib/helpers/format-number";
|
||||||
import { styled } from "../../lib/styles/stitches.config";
|
import { styled } from "../../lib/styles/stitches.config";
|
||||||
import type { RepositoryType } from "../../types";
|
import type { Repository } from "../../types";
|
||||||
|
|
||||||
const Wrapper = styled("div", {
|
const Wrapper = styled("div", {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
@ -68,7 +68,7 @@ const LanguageCircle = styled("span", {
|
|||||||
verticalAlign: "text-top",
|
verticalAlign: "text-top",
|
||||||
});
|
});
|
||||||
|
|
||||||
export type RepositoryCardProps = RepositoryType & {
|
export type RepositoryCardProps = Repository & {
|
||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
// Next.js constants (not needed in frontend)
|
// Next.js constants (not needed in frontend)
|
||||||
|
|
||||||
|
// directory containing .mdx files relative to project root
|
||||||
export const NOTES_DIR = "./notes";
|
export const NOTES_DIR = "./notes";
|
||||||
|
|
||||||
// normalize the timestamp saved when building/deploying (see next.config.js) and fall back to right now:
|
// normalize the timestamp saved when building/deploying (see next.config.js) and fall back to right now:
|
||||||
|
@ -19,20 +19,27 @@ import remarkGfm from "remark-gfm";
|
|||||||
import rehypeSlug from "rehype-slug";
|
import rehypeSlug from "rehype-slug";
|
||||||
import rehypePrism from "rehype-prism-plus";
|
import rehypePrism from "rehype-prism-plus";
|
||||||
|
|
||||||
import type { NoteType } from "../../types";
|
import type { Note, NoteFrontMatter } from "../../types";
|
||||||
|
|
||||||
|
const ABSOLUTE_NOTES_DIR = path.join(process.cwd(), NOTES_DIR);
|
||||||
|
|
||||||
// returns all .mdx files in NOTES_DIR (without .mdx extension)
|
// returns all .mdx files in NOTES_DIR (without .mdx extension)
|
||||||
export const getNoteSlugs = async (): Promise<string[]> => {
|
export const getNoteSlugs = async (): Promise<string[]> => {
|
||||||
// get all files in NOTES_DIR
|
// get all files in NOTES_DIR
|
||||||
const files = await fs.readdir(path.join(process.cwd(), NOTES_DIR));
|
const files = await fs.readdir(ABSOLUTE_NOTES_DIR);
|
||||||
|
|
||||||
// narrow to only the .mdx files and strip the .mdx extension
|
// narrow to only the .mdx files and strip the .mdx extension
|
||||||
return files.filter((file) => /\.mdx$/.test(file)).map((noteFile) => noteFile.replace(/\.mdx$/, ""));
|
return files.filter((file) => /\.mdx$/.test(file)).map((noteFile) => noteFile.replace(/\.mdx$/, ""));
|
||||||
};
|
};
|
||||||
|
|
||||||
// returns front matter and/or *raw* markdown contents of a given slug
|
// returns front matter and/or *raw* markdown contents of a given slug
|
||||||
export const getNoteData = async (slug: string): Promise<Omit<NoteType, "source"> & { content: string }> => {
|
export const getNoteData = async (
|
||||||
const fullPath = path.join(process.cwd(), NOTES_DIR, `${slug}.mdx`);
|
slug: string
|
||||||
|
): Promise<{
|
||||||
|
frontMatter: NoteFrontMatter;
|
||||||
|
content: string;
|
||||||
|
}> => {
|
||||||
|
const fullPath = path.join(ABSOLUTE_NOTES_DIR, `${slug}.mdx`);
|
||||||
const rawContent = await fs.readFile(fullPath, "utf8");
|
const rawContent = await fs.readFile(fullPath, "utf8");
|
||||||
const { data, content } = matter(rawContent);
|
const { data, content } = matter(rawContent);
|
||||||
|
|
||||||
@ -52,7 +59,7 @@ export const getNoteData = async (slug: string): Promise<Omit<NoteType, "source"
|
|||||||
// return both the parsed YAML front matter (with a few amendments) and the raw, unparsed markdown content
|
// return both the parsed YAML front matter (with a few amendments) and the raw, unparsed markdown content
|
||||||
return {
|
return {
|
||||||
frontMatter: {
|
frontMatter: {
|
||||||
...(data as Omit<NoteType["frontMatter"], "slug" | "title" | "htmlTitle" | "permalink" | "date" | "readingMins">),
|
...(data as Partial<NoteFrontMatter>),
|
||||||
// zero markdown title:
|
// zero markdown title:
|
||||||
title: removeMarkdown(data.title),
|
title: removeMarkdown(data.title),
|
||||||
// parsed markdown title:
|
// parsed markdown title:
|
||||||
@ -67,7 +74,7 @@ export const getNoteData = async (slug: string): Promise<Omit<NoteType, "source"
|
|||||||
};
|
};
|
||||||
|
|
||||||
// fully parses MDX into JS and returns *everything* about a note
|
// fully parses MDX into JS and returns *everything* about a note
|
||||||
export const getNote = async (slug: string): Promise<NoteType> => {
|
export const getNote = async (slug: string): Promise<Note> => {
|
||||||
const { frontMatter, content } = await getNoteData(slug);
|
const { frontMatter, content } = await getNoteData(slug);
|
||||||
const source = await serialize(content, {
|
const source = await serialize(content, {
|
||||||
parseFrontmatter: false,
|
parseFrontmatter: false,
|
||||||
@ -99,7 +106,7 @@ export const getNote = async (slug: string): Promise<NoteType> => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// returns the front matter of ALL notes, sorted reverse chronologically
|
// returns the front matter of ALL notes, sorted reverse chronologically
|
||||||
export const getAllNotes = async (): Promise<NoteType["frontMatter"][]> => {
|
export const getAllNotes = async (): Promise<NoteFrontMatter[]> => {
|
||||||
const slugs = await getNoteSlugs();
|
const slugs = await getNoteSlugs();
|
||||||
|
|
||||||
// for each slug, query its front matter
|
// for each slug, query its front matter
|
||||||
@ -108,9 +115,7 @@ export const getAllNotes = async (): Promise<NoteType["frontMatter"][]> => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// sort the results by date
|
// sort the results by date
|
||||||
const sorted = data.sort((note1: NoteType["frontMatter"], note2: NoteType["frontMatter"]) =>
|
const sorted = data.sort((note1, note2) => (note1.date > note2.date ? -1 : 1));
|
||||||
note1.date > note2.date ? -1 : 1
|
|
||||||
);
|
|
||||||
|
|
||||||
return sorted;
|
return sorted;
|
||||||
};
|
};
|
||||||
|
@ -10,9 +10,9 @@ import { getNote, getNoteSlugs } from "../../lib/helpers/parse-notes";
|
|||||||
import * as config from "../../lib/config";
|
import * as config from "../../lib/config";
|
||||||
import { articleJsonLd } from "../../lib/config/seo";
|
import { articleJsonLd } from "../../lib/config/seo";
|
||||||
import type { GetStaticProps, GetStaticPaths } from "next";
|
import type { GetStaticProps, GetStaticPaths } from "next";
|
||||||
import type { NoteType } from "../../types";
|
import type { Note, NoteFrontMatter } from "../../types";
|
||||||
|
|
||||||
const Note = ({ frontMatter, source }: NoteType) => {
|
const Note = ({ frontMatter, source }: Note) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NextSeo
|
<NextSeo
|
||||||
@ -74,7 +74,7 @@ const Note = ({ frontMatter, source }: NoteType) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps = async ({ params }: { params: Pick<NoteType["frontMatter"], "slug"> }) => {
|
export const getStaticProps: GetStaticProps = async ({ params }: { params: Pick<NoteFrontMatter, "slug"> }) => {
|
||||||
const { frontMatter, source } = await getNote(params.slug);
|
const { frontMatter, source } = await getNote(params.slug);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -8,7 +8,7 @@ import { OctocatOcticon } from "../components/Icons";
|
|||||||
import { styled } from "../lib/styles/stitches.config";
|
import { styled } from "../lib/styles/stitches.config";
|
||||||
import { authorSocial } from "../lib/config";
|
import { authorSocial } from "../lib/config";
|
||||||
import type { GetStaticProps } from "next";
|
import type { GetStaticProps } from "next";
|
||||||
import type { RepositoryType } from "../types";
|
import type { Repository } from "../types";
|
||||||
|
|
||||||
const Wrapper = styled("div", {
|
const Wrapper = styled("div", {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -54,7 +54,7 @@ const Projects = ({ repos }) => (
|
|||||||
|
|
||||||
<Content>
|
<Content>
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
{repos.map((repo: RepositoryType) => (
|
{repos.map((repo: Repository) => (
|
||||||
<Card key={repo.name} {...repo} />
|
<Card key={repo.name} {...repo} />
|
||||||
))}
|
))}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
@ -111,7 +111,7 @@ export const getStaticProps: GetStaticProps = async () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const repos: RepositoryType[] = user.repositories.edges.map(({ node: repo }) => ({
|
const repos: Repository[] = user.repositories.edges.map(({ node: repo }) => ({
|
||||||
name: repo.name,
|
name: repo.name,
|
||||||
url: repo.url,
|
url: repo.url,
|
||||||
description: repo.description,
|
description: repo.description,
|
||||||
|
29
types/note.d.ts
vendored
29
types/note.d.ts
vendored
@ -1,18 +1,21 @@
|
|||||||
import type { MDXRemoteSerializeResult } from "next-mdx-remote";
|
import type { MDXRemoteSerializeResult } from "next-mdx-remote";
|
||||||
|
|
||||||
export type NoteType = {
|
export type NoteFrontMatter = {
|
||||||
frontMatter: {
|
slug: string;
|
||||||
slug: string;
|
permalink: string;
|
||||||
permalink: string;
|
date: string;
|
||||||
date: string;
|
title: string;
|
||||||
title: string;
|
htmlTitle?: string;
|
||||||
htmlTitle?: string;
|
description?: string;
|
||||||
description?: string;
|
image?: string;
|
||||||
image?: string;
|
tags?: string[];
|
||||||
tags?: string[];
|
readingMins?: number;
|
||||||
readingMins?: number;
|
noComments?: boolean;
|
||||||
noComments?: boolean;
|
};
|
||||||
};
|
|
||||||
|
export type Note = {
|
||||||
|
// yaml metadata
|
||||||
|
frontMatter: NoteFrontMatter;
|
||||||
|
|
||||||
// the final, compiled JSX by next-mdx-remote; see lib/helpers/parse-notes.ts
|
// the final, compiled JSX by next-mdx-remote; see lib/helpers/parse-notes.ts
|
||||||
source: MDXRemoteSerializeResult;
|
source: MDXRemoteSerializeResult;
|
||||||
|
2
types/repository.d.ts
vendored
2
types/repository.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
export type RepositoryType = {
|
export type Repository = {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user