diff --git a/components/content.tsx b/components/content.tsx index d05940b4..731cd9a9 100644 --- a/components/content.tsx +++ b/components/content.tsx @@ -1,4 +1,4 @@ -import Menu from "../components/menu"; +import Menu from "./menu"; import { DiscordIcon, GitHubIcon } from "./icons"; import React, { useEffect, useMemo, useRef, useState } from "react"; import Link from "next/link"; diff --git a/components/menu.jsx b/components/menu.tsx similarity index 97% rename from components/menu.jsx rename to components/menu.tsx index bc53d8f0..07f6cb32 100644 --- a/components/menu.jsx +++ b/components/menu.tsx @@ -1,6 +1,5 @@ import { Fragment, useCallback, useState } from "react"; import classnames from "classnames"; -import Link from "next/link"; const monthNames = [ "January", @@ -130,7 +129,8 @@ function Level2({ href, menu }) { return ; } -function pagesFor(menu) { +// TODO: Type the menu hierarchy +function pagesFor(menu: Record) { return Object.entries(menu).map(([, entry]) => { if (entry.page) { return { diff --git a/lib/api.js b/lib/api.ts similarity index 86% rename from lib/api.js rename to lib/api.ts index a760b7e6..bacf3793 100644 --- a/lib/api.js +++ b/lib/api.ts @@ -2,14 +2,15 @@ import fs from "fs"; import glob from "glob"; import path from "path"; import matter from "gray-matter"; -import util from "util"; -import { toHTML } from "./markdown.js"; +import { toHTML } from "./markdown"; const contentDir = path.join(process.cwd(), "content").replace(/\\/g, "/"); // Merge app level props in with page props -export function withAppProps(props = { props: {} }) { +export function withAppProps( + props: { props: Record } = { props: {} } +) { const blog = getLastBlog(); delete blog.body; props.props.app = { @@ -64,7 +65,6 @@ export async function getProps(menu, slug) { const page = loadPage(`${slug}`); page.body = await toHTML(page.body); - const sectionTitle = menu[root].title; const normalized = [ { key: root, @@ -86,31 +86,39 @@ export async function getProps(menu, slug) { function setPrevNext(page, menu) { let didMatch = false; - eachPage(menu, (p, prev) => { - if (p.href == page.href) { - didMatch = true; - - if (prev && prev.title) { - page.prev = { - title: prev.menuTitle || prev.title, - href: prev.href, + eachPage( + menu, + (p, prev) => { + if (p.href == page.href) { + didMatch = true; + + if (prev && prev.title) { + page.prev = { + title: prev.menuTitle || prev.title, + href: prev.href, + }; + } + } else if (didMatch) { + page.next = { + title: p.menuTitle || p.title, + href: p.href, }; - } - } else if (didMatch) { - page.next = { - title: p.menuTitle || p.title, - href: p.href, - }; - didMatch = false; - } - }); + didMatch = false; + } + }, + undefined, + undefined + ); return page; } // Build a list of paths from the sitemap -function collectPaths(level, prefix = "") { +function collectPaths( + level: Record, + prefix = "" +) { let out = []; for (const [k, v] of Object.entries(level)) { diff --git a/lib/blog.js b/lib/blog.ts similarity index 90% rename from lib/blog.js rename to lib/blog.ts index 37e9c0c1..a15c09c6 100644 --- a/lib/blog.js +++ b/lib/blog.ts @@ -9,10 +9,10 @@ function cachedPaths() { return paths; } -export function getBlogPostsByYear({ limit } = {}) { +export function getBlogPostsByYear(limit?: number) { let count = 0; return cachedPaths().reduce((years, post) => { - if (limit != null && count >= limit) { + if (limit !== undefined && count >= limit) { return years; } const date = new Date(post.date); diff --git a/lib/markdown.js b/lib/markdown.ts similarity index 93% rename from lib/markdown.js rename to lib/markdown.ts index 5f3d4930..6a6b1d1c 100644 --- a/lib/markdown.js +++ b/lib/markdown.ts @@ -1,4 +1,3 @@ -import { stream } from "unified-stream"; import { unified } from "unified"; import remarkParse from "remark-parse"; import remarkRehype from "remark-rehype"; @@ -80,11 +79,13 @@ export const toHTML = async (raw) => { await unified() .use(remarkParse) .use(remarkCodeRemoveSomeLines) + // @ts-expect-error: unified's plugin type mistakenly selects the wrong union overload .use(remarkRehype, { allowDangerousHtml: true }) .use(rehypeHighlight, rehypeHighlightOptions) .use(rehypeRaw) .use(rehypeSlug) .use(rehyperBlockquotePlus, rehyperBlockquotePlusOptions) + // @ts-expect-error: unified's plugin type mistakenly selects the Array union variant .use(rehypeStringify) .process(raw) ); diff --git a/lib/page.js b/lib/page.tsx similarity index 100% rename from lib/page.js rename to lib/page.tsx diff --git a/package-lock.json b/package-lock.json index 7a1c4e98..1fdb6155 100644 --- a/package-lock.json +++ b/package-lock.json @@ -579,9 +579,9 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "optional": true, "os": [ @@ -2578,9 +2578,9 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, "glob": { diff --git a/package.json b/package.json index 0461c6e8..605d434f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "next dev", "build": "next build && npm run build:rss && next export", - "build:rss": "node ./scripts/generate-rss-feed.js", + "build:rss": "tsc --outDir dist --noEmit false && sed -i 's/markdown\"/markdown.js\"/g' dist/lib/api.js && node scripts/generate-rss-feed.js", "start": "next start", "fmt": "prettier --write --prose-wrap always '{components,content,pages,lib,styles}/**/*.{js,jsx,ts,tsx,scss}'", "fmt:check": "prettier --check --prose-wrap always '{components,content,pages,lib,styles}/**/*.{js,jsx,ts,tsx,scss}'" diff --git a/pages/[...slug].jsx b/pages/[...slug].tsx similarity index 100% rename from pages/[...slug].jsx rename to pages/[...slug].tsx diff --git a/pages/blog.jsx b/pages/blog.tsx similarity index 84% rename from pages/blog.jsx rename to pages/blog.tsx index e71fd6d4..f8cde65b 100644 --- a/pages/blog.jsx +++ b/pages/blog.tsx @@ -3,7 +3,13 @@ import Layout from "../components/layout"; import * as blog from "../lib/blog"; import * as api from "../lib/api"; -export default function Blog({ app, postsByYear }) { +type Props = { + app: any; + // TODO: Properly type the posts + postsByYear: Record; +}; + +export default function Blog({ app, postsByYear }: Props) { return (
@@ -13,7 +19,7 @@ export default function Blog({ app, postsByYear }) {

Blog Posts

{Object.entries(postsByYear) .reverse() - .map(([year, { key, title, nested }]) => ( + .map(([year, { title, nested }]) => ( ))} diff --git a/pages/blog/[...slug].jsx b/pages/blog/[...slug].tsx similarity index 87% rename from pages/blog/[...slug].jsx rename to pages/blog/[...slug].tsx index 0af22e39..c3c91592 100644 --- a/pages/blog/[...slug].jsx +++ b/pages/blog/[...slug].tsx @@ -22,11 +22,10 @@ export async function getStaticPaths() { export async function getStaticProps({ params: { slug: slugParam } }) { let slug = slugParam[0]; - let postsByYear = blog.getBlogPostsByYear({ - limit: SIDEBAR_POST_COUNT, - }); + let postsByYear = blog.getBlogPostsByYear(SIDEBAR_POST_COUNT); - const page = content.loadPage(`blog/${slug}`); + // TODO: Properly type the page content + const page: any = content.loadPage(`blog/${slug}`); page.body = await toHTML(page.body); let next = blog.getNextPost(slug); diff --git a/scripts/generate-rss-feed.js b/scripts/generate-rss-feed.js index cf83ff10..78d7cdaa 100644 --- a/scripts/generate-rss-feed.js +++ b/scripts/generate-rss-feed.js @@ -1,5 +1,5 @@ import RSS from "rss"; -import { getDateOrderedPaths } from "../lib/api.js"; +import { getDateOrderedPaths } from "../dist/lib/api.js"; import fs from "fs"; const siteUrl = "https://tokio.rs";