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";