Commit d843c51

HPCesia <me@hpcesia.com>
2026-10-10 06:38:47
style: format with treefmt
1 parent 8759c69
src/components/widgets/LocaleSwitcher.astro
@@ -20,22 +20,21 @@ const getLocaleUrl = (target: Locale) =>
   getRelativeLocaleUrl(getPathWithoutLocale(currentPath), target) +
   Astro.url.search;
 ---
+
 <select
   class="locale-switcher"
   aria-label={globalI18n.language}
   onchange="location.href = this.value"
 >
-  {
-    availableLocales.map((target) => (
-      <option
-        value={getLocaleUrl(target)}
-        selected={target === locale}
-        lang={target}
-      >
-        {getLocaleName(getLocaleLang(target), target)}
-      </option>
-    ))
-  }
+  {availableLocales.map((target) => (
+    <option
+      value={getLocaleUrl(target)}
+      selected={target === locale}
+      lang={target}
+    >
+      {getLocaleName(getLocaleLang(target), target)}
+    </option>
+  ))}
 </select>
 
 <style lang="scss" is:global>
src/components/widgets/PostsList.astro
@@ -16,23 +16,22 @@ const postUrl = (post) => {
   return getRelativeLocaleUrl(slug, locale);
 };
 ---
+
 <nav class="posts-list">
   <ol>
-    {
-      posts.map((post) => {
-        const dt = Temporal.ZonedDateTime.from(post.data.date).toPlainDateTime();
-        return (
-          <li>
-            <a href={postUrl(post)}>
-              {post.data.title}
-            </a>
-            <time datetime={dt.toString()}>
-              {dt.toPlainDate().toLocaleString(Astro.currentLocale || DEFAULT_LOCALE)}
-            </time>
-          </li>
-        );
-      })
-    }
+    {posts.map((post) => {
+      const dt = Temporal.ZonedDateTime.from(post.data.date).toPlainDateTime();
+      return (
+        <li>
+          <a href={postUrl(post)}>{post.data.title}</a>
+          <time datetime={dt.toString()}>
+            {dt
+              .toPlainDate()
+              .toLocaleString(Astro.currentLocale || DEFAULT_LOCALE)}
+          </time>
+        </li>
+      );
+    })}
   </ol>
 </nav>
 
src/components/Footer.astro
@@ -7,6 +7,7 @@ import { getLocaleFeedUrl } from "@/utils/url.ts";
 const locale = Astro.currentLocale! as Locale;
 const globalI18n = getIntlayer("global", locale);
 ---
+
 <footer class="footer">
   <div class="footer-alternatives">
     <a href={getLocaleFeedUrl(locale)}>
@@ -16,8 +17,13 @@ const globalI18n = getIntlayer("global", locale);
   </div>
   <div class="footer-colophon">
     <span>Copyright © {new Date().getFullYear()} {SITE_CONFIG.author}</span>
-    <span>Powered by <a href="https://astro.build/">Astro</a> and <a href="https://typst.app/">Typst</a></span>
-    <span>Theme <a href="https://git.trin.one/HPCesia/kerplunk">Kerplunk</a></span>
+    <span>
+      Powered by <a href="https://astro.build/">Astro</a> and
+      <a href="https://typst.app/">Typst</a>
+    </span>
+    <span>
+      Theme <a href="https://git.trin.one/HPCesia/kerplunk">Kerplunk</a>
+    </span>
   </div>
 </footer>
 
src/components/Header.astro
@@ -1,11 +1,9 @@
 ---
 import { getIntlayer, type Locale } from "intlayer";
-
+import LocaleSwitcher from "@/components/widgets/LocaleSwitcher.astro";
 import { SITE_CONFIG } from "@/config.ts";
 import { getRelativeLocaleUrl } from "@/utils/url.ts";
 
-import LocaleSwitcher from "@/components/widgets/LocaleSwitcher.astro";
-
 interface Props {
   availableLocales: Locale[];
 }
@@ -14,14 +12,26 @@ const { availableLocales } = Astro.props;
 const locale = Astro.currentLocale! as Locale;
 const globalI18n = getIntlayer("global", locale);
 ---
+
 <header class="header">
-  <a class="header-home"
-    href={getRelativeLocaleUrl("/", locale)}>{SITE_CONFIG.title}</a>
+  <a class="header-home" href={getRelativeLocaleUrl("/", locale)}
+    >{SITE_CONFIG.title}</a
+  >
   <nav>
     <ul>
-      <li><a href={getRelativeLocaleUrl("/posts", locale)}>{globalI18n.posts.title}</a></li>
-      <li><a href={getRelativeLocaleUrl("/about", locale)}>{globalI18n.about}</a></li>
-      <li><a href={getRelativeLocaleUrl("/links", locale)}>{globalI18n.friendLinks}</a></li>
+      <li>
+        <a href={getRelativeLocaleUrl("/posts", locale)}
+          >{globalI18n.posts.title}</a
+        >
+      </li>
+      <li>
+        <a href={getRelativeLocaleUrl("/about", locale)}>{globalI18n.about}</a>
+      </li>
+      <li>
+        <a href={getRelativeLocaleUrl("/links", locale)}
+          >{globalI18n.friendLinks}</a
+        >
+      </li>
     </ul>
     <LocaleSwitcher availableLocales={availableLocales} />
   </nav>
src/integrations/extract-images.ts
@@ -28,18 +28,17 @@ const EXT_BY_MIME: Record<string, string> = {
 const IMG_TAG = /<img\b[^>]*>/g;
 const IMG_SRC = /src=(["'])(data:image\/[^"']+)\1/;
 
-function imageInfo(
-  src: string,
-): { bytes: Buffer; filename: string } | null {
+function imageInfo(src: string): { bytes: Buffer; filename: string } | null {
   const match = src.match(/^data:image\/([^;]+);base64,([A-Za-z0-9+/=]+)$/);
   if (!match) return null;
   const ext = EXT_BY_MIME[match[1]];
   if (!ext) return null;
   const bytes = Buffer.from(match[2], "base64");
-  const hash = crypto.createHash("sha256").update(bytes).digest("hex").slice(
-    0,
-    12,
-  );
+  const hash = crypto
+    .createHash("sha256")
+    .update(bytes)
+    .digest("hex")
+    .slice(0, 12);
   return { bytes, filename: `${hash}.${ext}` };
 }
 
@@ -118,7 +117,7 @@ export function extractImages(): AstroIntegration {
           await fs.mkdir(outDir, { recursive: true });
           await Promise.all(
             [...written].map(([filename, bytes]) =>
-              fs.writeFile(path.join(outDir, filename), bytes)
+              fs.writeFile(path.join(outDir, filename), bytes),
             ),
           );
           logger.info(
src/layouts/BaseLayout.astro
@@ -1,7 +1,8 @@
 ---
 import { Font } from "astro:assets";
 import { getIntlayer, type Locale } from "intlayer";
-
+import Footer from "@/components/Footer.astro";
+import Header from "@/components/Header.astro";
 import { DEFAULT_LOCALE, SITE_CONFIG } from "@/config";
 import {
   getLocaleFeedUrl,
@@ -10,9 +11,6 @@ import {
   url,
 } from "@/utils/url.ts";
 
-import Footer from "@/components/Footer.astro";
-import Header from "@/components/Header.astro";
-
 import "sanitize.css/sanitize.css";
 import "@/styles/global.scss";
 
@@ -36,7 +34,7 @@ const {
 } = Astro.props;
 
 const pageLocales = SITE_CONFIG.locales.filter((candidate) =>
-  availableLocales.includes(candidate)
+  availableLocales.includes(candidate),
 );
 
 if (!pageLocales.includes(DEFAULT_LOCALE)) {
@@ -45,57 +43,64 @@ if (!pageLocales.includes(DEFAULT_LOCALE)) {
   );
 }
 
-const getAbsoluteLocaleUrl = (
-  path: string,
-  locale: Locale,
-) => new URL(getRelativeLocaleUrl(path, locale), Astro.site).toString();
+const getAbsoluteLocaleUrl = (path: string, locale: Locale) =>
+  new URL(getRelativeLocaleUrl(path, locale), Astro.site).toString();
 ---
+
 <!doctype html>
 <html lang={locale}>
   <head>
-    <meta charset="utf-8" />
-    <meta name="viewport" content="width=device-width" />
-    <meta name="generator" content={Astro.generator} />
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width">
+    <meta name="generator" content={Astro.generator}>
 
-    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
-    <link rel="icon" href="/favicon.ico" />
-    <link rel="sitemap" href="/sitemap-index.xml" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.svg">
+    <link rel="icon" href="/favicon.ico">
+    <link rel="sitemap" href="/sitemap-index.xml">
     <link
       rel="alternate"
       type="application/atom+xml"
       hreflang={locale ?? DEFAULT_LOCALE}
       title="Atom Feed"
       href={getLocaleFeedUrl(locale ?? DEFAULT_LOCALE)}
-    />
+    >
     <link
       rel="alternate"
       type="application/atom+xml"
       title="Atom Feed"
       href={url("/feed.atom")}
-    />
+    >
 
     <title>{title}</title>
-    <meta name="title" content={title} />
-    <meta name="description" content={description} />
-    <meta name="author" content={author} />
-
-    {
-      pageLocales.map((target) => (
-        <link rel="alternate" hreflang={target}
-          href={getAbsoluteLocaleUrl(getPathWithoutLocale(Astro.url.pathname), target)}
-        >
-      ))
-    }
-    <link rel="alternate" hreflang="x-default"
-      href={getAbsoluteLocaleUrl(getPathWithoutLocale(Astro.url.pathname), DEFAULT_LOCALE)}
+    <meta name="title" content={title}>
+    <meta name="description" content={description}>
+    <meta name="author" content={author}>
+
+    {pageLocales.map((target) => (
+      <link
+        rel="alternate"
+        hreflang={target}
+        href={getAbsoluteLocaleUrl(
+          getPathWithoutLocale(Astro.url.pathname),
+          target,
+        )}
+      >
+    ))}
+    <link
+      rel="alternate"
+      hreflang="x-default"
+      href={getAbsoluteLocaleUrl(
+        getPathWithoutLocale(Astro.url.pathname),
+        DEFAULT_LOCALE,
+      )}
     >
 
-    <meta property="og:url" content={Astro.url} />
-    <meta property="og:site_name" content={SITE_CONFIG.title} />
-    <meta property="og:title" content={title} />
-    <meta property="og:description" content={description} />
-    <meta property="og:locale" content={locale} />
-    <meta property="og:type" content={ogType} />
+    <meta property="og:url" content={Astro.url}>
+    <meta property="og:site_name" content={SITE_CONFIG.title}>
+    <meta property="og:title" content={title}>
+    <meta property="og:description" content={description}>
+    <meta property="og:locale" content={locale}>
+    <meta property="og:type" content={ogType}>
 
     <meta name="robots" content="noindex, nofollow">
 
src/pages/[...locale]/posts/[slug].astro
@@ -1,12 +1,11 @@
 ---
-import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
 import { getCollection, render } from "astro:content";
+import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
 
 import { SITE_CONFIG } from "@/config.ts";
+import BaseLayout from "@/layouts/BaseLayout.astro";
 import { getPostsLocaleMap } from "@/utils/content.ts";
 import { getLocaleRouteParam } from "@/utils/url.ts";
-
-import BaseLayout from "@/layouts/BaseLayout.astro";
 import "@/styles/article/index.scss";
 
 type Props = InferGetStaticPropsType<typeof getStaticPaths>;
@@ -16,21 +15,23 @@ export const getStaticPaths = (async () => {
   const postsLocaleMap = getPostsLocaleMap(posts);
 
   return Object.entries(postsLocaleMap).flatMap(([slug, localeMap]) => {
-    const availableLocales = SITE_CONFIG.locales.filter((locale) =>
-      localeMap[locale] !== undefined
+    const availableLocales = SITE_CONFIG.locales.filter(
+      (locale) => localeMap[locale] !== undefined,
     );
 
-    return SITE_CONFIG.locales.map((locale) => {
-      const entry = localeMap[locale];
-      if (entry === undefined) {
-        return undefined;
-      } else {
-        return {
-          params: { locale: getLocaleRouteParam(locale), slug },
-          props: { entry, availableLocales },
-        };
-      }
-    }).filter((i) => i !== undefined);
+    return SITE_CONFIG.locales
+      .map((locale) => {
+        const entry = localeMap[locale];
+        if (entry === undefined) {
+          return undefined;
+        } else {
+          return {
+            params: { locale: getLocaleRouteParam(locale), slug },
+            props: { entry, availableLocales },
+          };
+        }
+      })
+      .filter((i) => i !== undefined);
   });
 }) satisfies GetStaticPaths;
 
@@ -39,6 +40,7 @@ const { entry, availableLocales } = Astro.props;
 const data = entry.data;
 const { Content } = await render(entry);
 ---
+
 <BaseLayout
   title={data.title}
   author={data.author}
@@ -50,11 +52,14 @@ const { Content } = await render(entry);
     <Content />
     <footer>
       <small>
-        <p>License: {
-          typeof data.license === "string"
-          ? data.license
-          : <a href={data.license.link}>{data.license.name}</a>
-        }</p>
+        <p>
+          License:
+          {typeof data.license === "string" ? (
+            data.license
+          ) : (
+            <a href={data.license.link}>{data.license.name}</a>
+          )}
+        </p>
       </small>
     </footer>
   </article>
src/pages/[...locale]/posts/index.astro
@@ -1,15 +1,13 @@
 ---
-import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
 import { getCollection } from "astro:content";
+import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
 import { getIntlayer } from "intlayer";
-
+import PostsList from "@/components/widgets/PostsList.astro";
 import { SITE_CONFIG } from "@/config.ts";
+import BaseLayout from "@/layouts/BaseLayout.astro";
 import { getLocalePosts } from "@/utils/content.ts";
 import { getLocaleRouteParam } from "@/utils/url.ts";
 
-import BaseLayout from "@/layouts/BaseLayout.astro";
-import PostsList from "@/components/widgets/PostsList.astro";
-
 type Props = InferGetStaticPropsType<typeof getStaticPaths>;
 
 export const getStaticPaths = (() => {
@@ -22,8 +20,8 @@ const locale = Astro.currentLocale;
 const globalI18n = getIntlayer("global", locale);
 
 const posts = getLocalePosts(await getCollection("posts"), locale);
-const sortedPosts = posts.sort(
-  (a, b) => Temporal.ZonedDateTime.compare(b.data.date, a.data.date),
+const sortedPosts = posts.sort((a, b) =>
+  Temporal.ZonedDateTime.compare(b.data.date, a.data.date),
 );
 const postsByYear = sortedPosts.reduce(
   (acc, post) => {
@@ -37,18 +35,17 @@ const postsByYear = sortedPosts.reduce(
   {} as Record<number, typeof posts>,
 );
 ---
+
 <BaseLayout title={globalI18n.posts.title}>
-  <div style={{fontSize: "1.2rem"}}>
+  <div style={{ fontSize: "1.2rem" }}>
     <h1>{globalI18n.posts.title}</h1>
-    {
-      Object.entries(postsByYear)
-        .reverse()
-        .map(([year, posts]) => (
-          <section>
-            <h2>{year}</h2>
-            <PostsList posts={posts} />
-          </section>
-        ))
-    }
+    {Object.entries(postsByYear)
+      .reverse()
+      .map(([year, posts]) => (
+        <section>
+          <h2>{year}</h2>
+          <PostsList posts={posts} />
+        </section>
+      ))}
   </div>
 </BaseLayout>
src/pages/[...locale]/about.astro
@@ -3,21 +3,22 @@ import type { GetStaticPaths } from "astro";
 import { getIntlayer } from "intlayer";
 
 import { SITE_CONFIG } from "@/config.ts";
+import BaseLayout from "@/layouts/BaseLayout.astro";
 import { loadLocaleContent } from "@/utils/content.ts";
 import { getLocaleRouteParam } from "@/utils/url.ts";
-
-import BaseLayout from "@/layouts/BaseLayout.astro";
 import "@/styles/article/index.scss";
 
-export const getStaticPaths: GetStaticPaths = () => (SITE_CONFIG.locales.map(
-  (locale) => ({ params: { locale: getLocaleRouteParam(locale) } }),
-));
+export const getStaticPaths: GetStaticPaths = () =>
+  SITE_CONFIG.locales.map((locale) => ({
+    params: { locale: getLocaleRouteParam(locale) },
+  }));
 
 const locale = Astro.currentLocale;
 const globalI18n = getIntlayer("global", locale);
 
 const { Content: Article } = await loadLocaleContent("about", locale);
 ---
+
 <BaseLayout title={globalI18n.about} ogType="article">
   <article>
     <h1>{globalI18n.about}</h1>
src/pages/[...locale]/index.astro
@@ -1,15 +1,13 @@
 ---
-import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
 import { getCollection } from "astro:content";
+import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
 import { getIntlayer } from "intlayer";
-
+import PostsList from "@/components/widgets/PostsList.astro";
 import { SITE_CONFIG } from "@/config.ts";
+import BaseLayout from "@/layouts/BaseLayout.astro";
 import { getLocalePosts, loadLocaleContent } from "@/utils/content.ts";
 import { shuffle } from "@/utils/random.ts";
 import { getLocaleRouteParam } from "@/utils/url.ts";
-
-import BaseLayout from "@/layouts/BaseLayout.astro";
-import PostsList from "@/components/widgets/PostsList.astro";
 import "@/styles/article/index.scss";
 
 type Props = InferGetStaticPropsType<typeof getStaticPaths>;
@@ -26,16 +24,17 @@ const globalI18n = getIntlayer("global", locale);
 const { Content: Article } = await loadLocaleContent("home", locale);
 
 const posts = getLocalePosts(await getCollection("posts"), locale);
-const sortedPosts = posts.sort(
-  (a, b) => Temporal.ZonedDateTime.compare(b.data.date, a.data.date),
+const sortedPosts = posts.sort((a, b) =>
+  Temporal.ZonedDateTime.compare(b.data.date, a.data.date),
 );
 ---
+
 <BaseLayout title="Kerplunk">
   <article>
     <h1>{SITE_CONFIG.title}</h1>
     <Article />
   </article>
-  <div style={{fontSize: "1.2rem"}}>
+  <div style={{ fontSize: "1.2rem" }}>
     <h2 id="recent-posts">{globalI18n.posts.recent}</h2>
     <PostsList posts={sortedPosts.slice(0, 5)} />
     <h2 id="recent-posts">{globalI18n.posts.random}</h2>
src/pages/404.astro
@@ -1,6 +1,7 @@
 ---
 import BaseLayout from "@/layouts/BaseLayout.astro";
 ---
+
 <BaseLayout>
   <div>404 Not Found</div>
 </BaseLayout>
src/pages/feed.[locale].atom.ts
@@ -1,5 +1,5 @@
-import type { APIRoute, GetStaticPaths } from "astro";
 import { getCollection } from "astro:content";
+import type { APIRoute, GetStaticPaths } from "astro";
 import type { Locale } from "intlayer";
 
 import { SITE_CONFIG } from "@/config.ts";
@@ -17,7 +17,7 @@ export const GET: APIRoute = async ({ site, params }) => {
   const origin = site.origin;
   const locale = params.locale as Locale;
   const posts = (await getCollection("posts")).filter((post) =>
-    post.id.startsWith(`${locale}/`)
+    post.id.startsWith(`${locale}/`),
   );
   const feed = await createFeed({
     id: new URL(getRelativeLocaleUrl("/", locale), origin).toString(),
src/pages/feed.atom.ts
@@ -1,5 +1,5 @@
-import type { APIRoute } from "astro";
 import { getCollection } from "astro:content";
+import type { APIRoute } from "astro";
 
 import { DEFAULT_LOCALE, SITE_CONFIG } from "@/config.ts";
 import { createFeed, localePostUrl } from "@/utils/feed.ts";
src/utils/plugins/rewrite-images.ts
@@ -1,5 +1,5 @@
-import type { RehypePlugin } from "@astrojs/markdown-remark";
 import { getImage } from "astro:assets";
+import type { RehypePlugin } from "@astrojs/markdown-remark";
 import { visit } from "unist-util-visit";
 
 import { ASSET_DIR, dataImageFilename } from "@/integrations/extract-images.ts";
@@ -33,9 +33,10 @@ function parseJsxString(literal: string | undefined): string {
 // `kp.img` renders Astro `<Image>` JSX into a script element. Feed readers
 // cannot execute it, so turn those scripts into plain `<img>` elements backed
 // by the same image service the pages use.
-export function rehypeRewriteJsxImages(
-  options: { site: string; width: number },
-): RehypePlugin {
+export function rehypeRewriteJsxImages(options: {
+  site: string;
+  width: number;
+}): RehypePlugin {
   return () => async (tree) => {
     const replacements: Replacement[] = [];
 
@@ -66,10 +67,7 @@ export function rehypeRewriteJsxImages(
           type: "element",
           tagName: "img",
           properties: {
-            src: new URL(
-              image?.src ?? url(source),
-              options.site,
-            ).toString(),
+            src: new URL(image?.src ?? url(source), options.site).toString(),
             alt: parseJsxString(jsx.match(JSX_IMAGE_ALT)?.[1]),
             width: image?.attributes.width,
             height: image?.attributes.height,
src/utils/content.ts
@@ -1,5 +1,5 @@
+import type { CollectionEntry } from "astro:content";
 import type { AstroComponentFactory } from "astro/runtime/server/index.js";
-import { type CollectionEntry } from "astro:content";
 
 import { DEFAULT_LOCALE } from "@/config.ts";
 
@@ -17,9 +17,10 @@ export async function loadLocaleContent(
   const hasFlatFile = Boolean(contents[`/src/contents/${name}.${locale}.typ`]);
   const hasNestFile = Boolean(contents[`/src/contents/${name}/${locale}.typ`]);
 
-  const resolvedLocale = (hasFlatFile || hasNestFile) ? locale : DEFAULT_LOCALE;
+  const resolvedLocale = hasFlatFile || hasNestFile ? locale : DEFAULT_LOCALE;
 
-  const loadedFile = contents[`/src/contents/${name}.${resolvedLocale}.typ`] ||
+  const loadedFile =
+    contents[`/src/contents/${name}.${resolvedLocale}.typ`] ||
     contents[`/src/contents/${name}/${resolvedLocale}.typ`];
   if (!loadedFile) {
     throw new Error(`Missing content: /src/contents/${name}.${locale}.typ`);
@@ -51,9 +52,9 @@ export function getLocalePosts(
   locale: string = DEFAULT_LOCALE,
 ) {
   const postsLocaleMap = getPostsLocaleMap(posts);
-  return Object.values(postsLocaleMap).map((
-    locales,
-  ) => (locales[locale] || locales[DEFAULT_LOCALE]));
+  return Object.values(postsLocaleMap).map(
+    (locales) => locales[locale] || locales[DEFAULT_LOCALE],
+  );
 }
 
 export function getPostLocaleSlug(post: CollectionEntry<"posts">) {
src/utils/feed.ts
@@ -3,8 +3,6 @@ import { Feed } from "feed";
 
 import { SITE_CONFIG } from "@/config.ts";
 import { getPostLocaleSlug } from "@/utils/content.ts";
-import { getRelativeLocaleUrl } from "@/utils/url.ts";
-
 import { rehypeAbsoluteLinks } from "@/utils/plugins/absolute-links.ts";
 import { rehypeCleanEndnotes } from "@/utils/plugins/clean-endnotes.ts";
 import { rehypeCleanProperties } from "@/utils/plugins/clean-properties.ts";
@@ -14,6 +12,7 @@ import {
   rehypeRewriteJsxImages,
 } from "@/utils/plugins/rewrite-images.ts";
 import { renderTypstToHtml } from "@/utils/render-typst.ts";
+import { getRelativeLocaleUrl } from "@/utils/url.ts";
 
 // Matches the `width` that `kp.img` passes to Astro's `<Image />`.
 const FEED_IMAGE_WIDTH = 780;
@@ -60,7 +59,7 @@ export async function createFeed(data: FeedData): Promise<Feed> {
   });
 
   const posts = [...data.posts].sort((a, b) =>
-    Temporal.ZonedDateTime.compare(b.data.date, a.data.date)
+    Temporal.ZonedDateTime.compare(b.data.date, a.data.date),
   );
 
   const items = await Promise.all(
@@ -71,9 +70,10 @@ export async function createFeed(data: FeedData): Promise<Feed> {
         id: link,
         link,
         description: post.data.desc,
-        content: typeof post.filePath === "string"
-          ? await renderFeedContent(post.filePath, data.site)
-          : undefined,
+        content:
+          typeof post.filePath === "string"
+            ? await renderFeedContent(post.filePath, data.site)
+            : undefined,
         author: [{ name: post.data.author || SITE_CONFIG.author }],
         date: new Date(
           Temporal.ZonedDateTime.from(post.data.date).epochMilliseconds,
src/utils/random.ts
@@ -1,16 +1,13 @@
 export function mulberry32(a: number) {
-  return function () {
-    let t = a += 0x6D2B79F5;
-    t = Math.imul(t ^ t >>> 15, t | 1);
-    t ^= t + Math.imul(t ^ t >>> 7, t | 61);
-    return ((t ^ t >>> 14) >>> 0) / 4294967296;
+  return () => {
+    let t = (a += 0x6d2b79f5);
+    t = Math.imul(t ^ (t >>> 15), t | 1);
+    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
+    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
   };
 }
 
-export function shuffle<T>(
-  arr: readonly T[],
-  generator = Math.random,
-): T[] {
+export function shuffle<T>(arr: readonly T[], generator = Math.random): T[] {
   const a = arr.slice();
   for (let i = a.length - 1; i > 0; i--) {
     const j = Math.floor(generator() * (i + 1));
src/utils/render-typst.ts
@@ -2,8 +2,8 @@ import { root } from "astro:config/server";
 import { fileURLToPath } from "node:url";
 
 import { NodeCompiler } from "@myriaddreamin/typst-ts-node-compiler";
-import { rehypeIt } from "astro-typst/dist/lib/rehype";
 import type { RehypePlugins } from "astro";
+import { rehypeIt } from "astro-typst/dist/lib/rehype";
 
 const $typst = NodeCompiler.create({
   workspace: fileURLToPath(root),
src/config.ts
@@ -16,8 +16,8 @@ export const DEFAULT_LOCALE = SITE_CONFIG.locales[0];
 
 const protocol = SITE_CONFIG.website.split("://")[0];
 const host = SITE_CONFIG.website.split("://")[1].split("/")[0];
-const basePath = SITE_CONFIG.website.split(host).slice(1).join("/") ||
-  undefined;
+const basePath =
+  SITE_CONFIG.website.split(host).slice(1).join("/") || undefined;
 export const WEBSITE = {
   protocol,
   host,
src/content.config.ts
@@ -1,69 +1,73 @@
 import { defineCollection } from "astro:content";
 import { glob } from "astro/loaders";
 import { z } from "astro/zod";
-import { type Locale } from "intlayer";
 import { slug as slugify } from "github-slugger";
+import type { Locale } from "intlayer";
 
 import { SITE_CONFIG } from "@/config.ts";
 
-const typCollection = (base: string) => (defineCollection({
-  loader: glob({
-    pattern: ["**/[^_]*.{typ,typst}", "!**/_*/**"],
-    base: "./src/contents/" + base,
-    generateId: ({ entry, data }) => {
-      const slugFromData = data.slug as string | undefined;
-      const filename = entry.split("/").at(-1);
-      const isFlatEntry = (filename.split(".").length > 2) &&
-        (SITE_CONFIG.locales.indexOf(filename.split(".").at(-2) as Locale) !==
-          -1);
-      const locale = filename.split(".").at(-2);
-      const slugFromEntry = isFlatEntry
-        ? filename.split(".").slice(0, -2).join("-")
-        : entry.split("/").at(-2);
-      return `${locale}/${slugify(slugFromData || slugFromEntry)}`;
-    },
-  }),
-  schema: z.object({
-    title: z.string(),
-    slug: z.string().optional(),
-    author: z.string().default(SITE_CONFIG.author),
-    desc: z.any().optional(),
-    date: z.string().transform((str) => {
-      const match = str.match(
-        /datetime\(\s*year:\s*(\d+),?\s*month:\s*(\d+),?\s*day:\s*(\d+)(?:,?\s*hour:\s*(\d+))?(?:,?\s*minute:\s*(\d+))?(?:,?\s*second:\s*(\d+))?,?\s*\)/,
-      );
-      if (match) {
-        const year = parseInt(match[1], 10);
-        const month = parseInt(match[2], 10);
-        const day = parseInt(match[3], 10);
-        const hour = match[4] ? parseInt(match[4], 10) : 0;
-        const minute = match[5] ? parseInt(match[5], 10) : 0;
-        const second = match[6] ? parseInt(match[6], 10) : 0;
-
-        return Temporal.ZonedDateTime.from({
-          year,
-          month,
-          day,
-          hour,
-          minute,
-          second,
-          timeZone: SITE_CONFIG.timeZone,
-        }).toString();
-      }
-      return z.NEVER;
+const typCollection = (base: string) =>
+  defineCollection({
+    loader: glob({
+      pattern: ["**/[^_]*.{typ,typst}", "!**/_*/**"],
+      base: "./src/contents/" + base,
+      generateId: ({ entry, data }) => {
+        const slugFromData = data.slug as string | undefined;
+        const filename = entry.split("/").at(-1);
+        const isFlatEntry =
+          filename.split(".").length > 2 &&
+          SITE_CONFIG.locales.indexOf(filename.split(".").at(-2) as Locale) !==
+            -1;
+        const locale = filename.split(".").at(-2);
+        const slugFromEntry = isFlatEntry
+          ? filename.split(".").slice(0, -2).join("-")
+          : entry.split("/").at(-2);
+        return `${locale}/${slugify(slugFromData || slugFromEntry)}`;
+      },
     }),
-    license: z.xor([
-      z.object({
-        name: z.string(),
-        link: z.url(),
+    schema: z.object({
+      title: z.string(),
+      slug: z.string().optional(),
+      author: z.string().default(SITE_CONFIG.author),
+      desc: z.any().optional(),
+      date: z.string().transform((str) => {
+        const match = str.match(
+          /datetime\(\s*year:\s*(\d+),?\s*month:\s*(\d+),?\s*day:\s*(\d+)(?:,?\s*hour:\s*(\d+))?(?:,?\s*minute:\s*(\d+))?(?:,?\s*second:\s*(\d+))?,?\s*\)/,
+        );
+        if (match) {
+          const year = parseInt(match[1], 10);
+          const month = parseInt(match[2], 10);
+          const day = parseInt(match[3], 10);
+          const hour = match[4] ? parseInt(match[4], 10) : 0;
+          const minute = match[5] ? parseInt(match[5], 10) : 0;
+          const second = match[6] ? parseInt(match[6], 10) : 0;
+
+          return Temporal.ZonedDateTime.from({
+            year,
+            month,
+            day,
+            hour,
+            minute,
+            second,
+            timeZone: SITE_CONFIG.timeZone,
+          }).toString();
+        }
+        return z.NEVER;
       }),
-      z.string(),
-    ]).default({
-      name: "CC BY-NC-SA 4.0",
-      link: "https://creativecommons.org/licenses/by-nc-sa/4.0/",
+      license: z
+        .xor([
+          z.object({
+            name: z.string(),
+            link: z.url(),
+          }),
+          z.string(),
+        ])
+        .default({
+          name: "CC BY-NC-SA 4.0",
+          link: "https://creativecommons.org/licenses/by-nc-sa/4.0/",
+        }),
     }),
-  }),
-}));
+  });
 
 export const collections = {
   posts: typCollection("posts"),
astro.config.ts
@@ -1,6 +1,5 @@
-import { defineConfig, fontProviders } from "astro/config";
-
 import sitemap from "@astrojs/sitemap";
+import { defineConfig, fontProviders } from "astro/config";
 import { intlayer } from "astro-intlayer";
 import { typst } from "astro-typst";
 
@@ -48,9 +47,7 @@ export default defineConfig({
     // But astro-typst only read this entry for it's own hast process
     // TODO: Replace with `markdown.processor = unified({rehypePlugins: [...]})`
     // after astro-typst add Astro v7 style config support
-    rehypePlugins: [
-      rehypeCleanEndnotes,
-    ],
+    rehypePlugins: [rehypeCleanEndnotes],
   },
   fonts: [
     {
intlayer.config.ts
@@ -1,4 +1,4 @@
-import { type IntlayerConfig } from "intlayer";
+import type { IntlayerConfig } from "intlayer";
 
 import { DEFAULT_LOCALE, SITE_CONFIG, WEBSITE } from "./src/config.ts";
 
tsconfig.json
@@ -1,19 +1,11 @@
 {
   "extends": "astro/tsconfigs/strict",
-  "include": [
-    ".astro/types.d.ts",
-    ".intlayer/**/*.ts",
-    "**/*"
-  ],
-  "exclude": [
-    "dist"
-  ],
+  "include": [".astro/types.d.ts", ".intlayer/**/*.ts", "**/*"],
+  "exclude": ["dist"],
   "compilerOptions": {
     "baseUrl": ".",
     "paths": {
-      "@/*": [
-        "./src/*"
-      ]
+      "@/*": ["./src/*"]
     }
   }
 }