From 1a81de76d542bf4bf4e1a7390bad001dc09e4b23 Mon Sep 17 00:00:00 2001
From: Yufan Sheng <syhily@gmail.com>
Date: Wed, 4 Dec 2024 11:48:19 +0800
Subject: [PATCH] feat: bump the astro and change the yaml meta to file loader.

---
 .vscode/settings.json                         |  1 +
 package-lock.json                             |  8 +--
 package.json                                  |  2 +-
 src/components/image/Image.astro              | 16 ++---
 src/components/image/UnstyledImage.astro      |  6 +-
 src/content.config.ts                         | 58 ++++++++----------
 src/content/categories/article.yml            |  7 ---
 src/content/categories/coding.yml             |  7 ---
 src/content/categories/gossip.yml             |  7 ---
 src/content/categories/notes.yml              |  6 --
 src/content/categories/novel.yml              |  6 --
 src/content/categories/think.yml              |  7 ---
 src/content/metas/categories.yml              | 40 +++++++++++++
 .../{friends/index.yml => metas/friends.yml}  | 59 ++++++++++++-------
 .../{tags/index.yml => metas/tags.yml}        |  0
 src/helpers/schema.ts                         | 43 ++++++++------
 16 files changed, 144 insertions(+), 129 deletions(-)
 delete mode 100644 src/content/categories/article.yml
 delete mode 100644 src/content/categories/coding.yml
 delete mode 100644 src/content/categories/gossip.yml
 delete mode 100644 src/content/categories/notes.yml
 delete mode 100644 src/content/categories/novel.yml
 delete mode 100644 src/content/categories/think.yml
 create mode 100644 src/content/metas/categories.yml
 rename src/content/{friends/index.yml => metas/friends.yml} (73%)
 rename src/content/{tags/index.yml => metas/tags.yml} (100%)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index f6eacf4..bf99f03 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -151,6 +151,7 @@
     "wechat",
     "weibo",
     "xiao",
+    "xiaoyu",
     "xinsenz",
     "xweb",
     "yefengs",
diff --git a/package-lock.json b/package-lock.json
index 21e7a7b..795a176 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,7 @@
         "@astrojs/mdx": "^4.0.1",
         "@astrojs/node": "^9.0.0",
         "@astrojs/rss": "^4.0.9",
-        "astro": "^5.0.1",
+        "astro": "^5.0.2",
         "drizzle-orm": "^0.37.0",
         "fuse.js": "^7.0.0",
         "glob": "^11.0.0",
@@ -2439,9 +2439,9 @@
       }
     },
     "node_modules/astro": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/astro/-/astro-5.0.1.tgz",
-      "integrity": "sha512-7XzFq3eFdSkeT/aCNealVv4klwmKoOYb6LZymbyZQrdUA9vEoUCKFcujVo4YbJJ8WXyEm515ZHPCxHTdDneEug==",
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/astro/-/astro-5.0.2.tgz",
+      "integrity": "sha512-MKf82vUiTZ2aK+c/8EDnLYIsToBdVVk4PuhhGdE8F/PcuUyS+oIcuCPf30iVf8WCQwXOfnYGnv1JbRjzkqUc3w==",
       "license": "MIT",
       "dependencies": {
         "@astrojs/compiler": "^2.10.3",
diff --git a/package.json b/package.json
index de013af..57fcfa8 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
     "@astrojs/mdx": "^4.0.1",
     "@astrojs/node": "^9.0.0",
     "@astrojs/rss": "^4.0.9",
-    "astro": "^5.0.1",
+    "astro": "^5.0.2",
     "drizzle-orm": "^0.37.0",
     "fuse.js": "^7.0.0",
     "glob": "^11.0.0",
diff --git a/src/components/image/Image.astro b/src/components/image/Image.astro
index f6ea08e..991c9d3 100644
--- a/src/components/image/Image.astro
+++ b/src/components/image/Image.astro
@@ -1,7 +1,7 @@
 ---
 import { blurStyle, type Image } from '@/helpers/images';
+import { getImage } from '@/helpers/schema';
 import options from '@/options';
-import { getEntry } from 'astro:content';
 
 interface Props extends Image {
   alt: string;
@@ -9,13 +9,13 @@ interface Props extends Image {
 
 let { alt, src, width, height, blurDataURL, blurWidth, blurHeight } = Astro.props;
 if (src.startsWith('/')) {
-  const image = await getEntry('images', src);
-  src = image.data.src;
-  width = image.data.width;
-  height = image.data.height;
-  blurDataURL = image.data.blurDataURL;
-  blurWidth = image.data.blurWidth;
-  blurHeight = image.data.blurHeight;
+  const image = getImage(src);
+  src = image.src;
+  width = image.width;
+  height = image.height;
+  blurDataURL = image.blurDataURL;
+  blurWidth = image.blurWidth;
+  blurHeight = image.blurHeight;
 }
 ---
 
diff --git a/src/components/image/UnstyledImage.astro b/src/components/image/UnstyledImage.astro
index 958b1bf..e3af1aa 100644
--- a/src/components/image/UnstyledImage.astro
+++ b/src/components/image/UnstyledImage.astro
@@ -1,6 +1,6 @@
 ---
 import type { Image } from '@/helpers/images';
-import { getEntry } from 'astro:content';
+import { getImage } from '@/helpers/schema';
 
 interface Props extends Image {
   alt: string;
@@ -8,8 +8,8 @@ interface Props extends Image {
 
 let { alt, src } = Astro.props;
 if (src.startsWith('/')) {
-  const image = await getEntry('images', src);
-  src = image.data.src;
+  const image = getImage(src);
+  src = image.src;
 }
 ---
 
diff --git a/src/content.config.ts b/src/content.config.ts
index 91880e1..b783471 100644
--- a/src/content.config.ts
+++ b/src/content.config.ts
@@ -1,7 +1,7 @@
 import { imageMetadata } from '@/helpers/images';
 import { urlJoin } from '@/helpers/tools';
 import options from '@/options';
-import { glob } from 'astro/loaders';
+import { file, glob } from 'astro/loaders';
 import { defineCollection, z } from 'astro:content';
 import { glob as Glob } from 'glob';
 import path from 'node:path';
@@ -67,7 +67,7 @@ const imagesCollection = defineCollection({
 
 // Categories Collection
 const categoriesCollection = defineCollection({
-  loader: glob({ pattern: '**\/[^_]*.yml', base: './src/content/categories' }),
+  loader: file('./src/content/metas/categories.yml'),
   schema: z.object({
     name: z.string().max(20),
     slug: slug(),
@@ -78,25 +78,24 @@ const categoriesCollection = defineCollection({
 
 // Friends Collection
 const friendsCollection = defineCollection({
-  loader: glob({ pattern: '**\/[^_]*.yml', base: './src/content/friends' }),
-  schema: z.array(
-    z
-      .object({
-        website: z.string().max(40),
-        description: z.string().optional(),
-        homepage: z.string().url(),
-        poster: z
-          .string()
-          .transform((poster) => (poster.startsWith('/') ? urlJoin(options.assetsPrefix(), poster) : poster)),
-        favicon: z.string().optional(),
-      })
-      .transform((data) => {
-        if (data.favicon === undefined) {
-          data.favicon = `${data.homepage}/favicon.ico`;
-        }
-        return data;
-      }),
-  ),
+  loader: file('./src/content/metas/friends.yml'),
+  schema: z.object({
+    website: z.string().max(40),
+    description: z.string().optional(),
+    homepage: z.string().url(),
+    poster: z
+      .string()
+      .transform((poster) => (poster.startsWith('/') ? urlJoin(options.assetsPrefix(), poster) : poster)),
+  }),
+});
+
+// Tags Collection
+const tagsCollection = defineCollection({
+  loader: file('./src/content/metas/tags.yml'),
+  schema: z.object({
+    name: z.string().max(20),
+    slug: slug(),
+  }),
 });
 
 // Posts Collection
@@ -133,22 +132,11 @@ const pagesCollection = defineCollection({
   }),
 });
 
-// Tags Collection
-const tagsCollection = defineCollection({
-  loader: glob({ pattern: '**\/[^_]*.yml', base: './src/content/tags' }),
-  schema: z.array(
-    z.object({
-      name: z.string().max(20),
-      slug: slug(),
-    }),
-  ),
-});
-
 export const collections = {
+  images: imagesCollection,
   categories: categoriesCollection,
   friends: friendsCollection,
-  pages: pagesCollection,
-  posts: postsCollection,
   tags: tagsCollection,
-  images: imagesCollection,
+  posts: postsCollection,
+  pages: pagesCollection,
 };
diff --git a/src/content/categories/article.yml b/src/content/categories/article.yml
deleted file mode 100644
index b218631..0000000
--- a/src/content/categories/article.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: 文章
-slug: article
-description: |-
-  我在寻找一个声音,期待着它把书影里的音符唱给你们听。
-  记录一本书、一个作者、一部电影及其与生活之间丝丝缕缕的情。
-  我热爱书和电影,更热爱生活,希望我们都有着走不完的似水流年,说不完的逝水年华。
-cover: /images/categories/article.jpg
diff --git a/src/content/categories/coding.yml b/src/content/categories/coding.yml
deleted file mode 100644
index f3c9b06..0000000
--- a/src/content/categories/coding.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: 编程
-slug: coding
-description: |-
-  冒泡排序,选择排序,插入排序,快速排序,堆排序,归并排序,希尔排序,桶排序,基数排序。
-  有向图,无向图,有环图,无环图,完全图,稠密图,稀疏图,拓扑图。
-  二叉树,红黑树,van Emde Boas树,最小生成树。
-cover: /images/categories/coding.jpg
diff --git a/src/content/categories/gossip.yml b/src/content/categories/gossip.yml
deleted file mode 100644
index 9aa47df..0000000
--- a/src/content/categories/gossip.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: 杂谈
-slug: gossip
-description: |-
-  我读书不过为消遣,偶至有趣处,便欣然记下。不敢说集腋成裘,但聊作敝帚自珍。
-  有伟人说,科学的世界像是海洋,他像在海边玩耍的孩子,偶尔捡拾到几只贝壳,他就很高兴。
-  海洋的比喻也可用作浩瀚的文史,行走在文史的典籍里,偶尔捡到一些边角料,也同样令人兴奋。
-cover: /images/categories/gossip.jpg
diff --git a/src/content/categories/notes.yml b/src/content/categories/notes.yml
deleted file mode 100644
index 7391a6d..0000000
--- a/src/content/categories/notes.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: 笔记
-slug: notes
-description: |-
-  风萧萧,天寥寥。山隐隐,木叶凋。小楼坐定,理书罢了。
-  灯青茶酽花静声悄,添几行斜书歪字,懒寻甚金缕玉箫。
-cover: /images/categories/notes.jpg
diff --git a/src/content/categories/novel.yml b/src/content/categories/novel.yml
deleted file mode 100644
index 5f2c299..0000000
--- a/src/content/categories/novel.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: 小说
-slug: novel
-description: |-
-  在这个世界里,没有朝霞的红,没有苔藓的绿,没有夜来香的黄,没有橡木的棕,也没有深海的蓝。
-  有的只是孩子们张惶不安地丈量世界,换来一声叹息。
-cover: /images/categories/novel.jpg
diff --git a/src/content/categories/think.yml b/src/content/categories/think.yml
deleted file mode 100644
index 5763b25..0000000
--- a/src/content/categories/think.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: 杂思
-slug: think
-description: |-
-  听一听素乐,品一品素茶,读一读素书,写一写素心。即使是清贫过一生,也安之若素。
-  只想在这滚滚红尘深处,留一抹清淡。只愿在这茫茫人海之中,寻一个会心。
-  爱读几句书,常听几支曲,闲品几盏茶,偶插几朵花。此生无所求,闲看花开落。
-cover: /images/categories/think.jpg
diff --git a/src/content/metas/categories.yml b/src/content/metas/categories.yml
new file mode 100644
index 0000000..57db426
--- /dev/null
+++ b/src/content/metas/categories.yml
@@ -0,0 +1,40 @@
+- name: 文章
+  slug: article
+  description: |-
+    我在寻找一个声音,期待着它把书影里的音符唱给你们听。
+    记录一本书、一个作者、一部电影及其与生活之间丝丝缕缕的情。
+    我热爱书和电影,更热爱生活,希望我们都有着走不完的似水流年,说不完的逝水年华。
+  cover: /images/categories/article.jpg
+- name: 杂谈
+  slug: gossip
+  description: |-
+    我读书不过为消遣,偶至有趣处,便欣然记下。不敢说集腋成裘,但聊作敝帚自珍。
+    有伟人说,科学的世界像是海洋,他像在海边玩耍的孩子,偶尔捡拾到几只贝壳,他就很高兴。
+    海洋的比喻也可用作浩瀚的文史,行走在文史的典籍里,偶尔捡到一些边角料,也同样令人兴奋。
+  cover: /images/categories/gossip.jpg
+- name: 杂思
+  slug: think
+  description: |-
+    听一听素乐,品一品素茶,读一读素书,写一写素心。即使是清贫过一生,也安之若素。
+    只想在这滚滚红尘深处,留一抹清淡。只愿在这茫茫人海之中,寻一个会心。
+    爱读几句书,常听几支曲,闲品几盏茶,偶插几朵花。此生无所求,闲看花开落。
+  cover: /images/categories/think.jpg
+- name: 编程
+  slug: coding
+  description: |-
+    冒泡排序,选择排序,插入排序,快速排序,堆排序,归并排序,希尔排序,桶排序,基数排序。
+    有向图,无向图,有环图,无环图,完全图,稠密图,稀疏图,拓扑图。
+    二叉树,红黑树,van Emde Boas树,最小生成树。
+  cover: /images/categories/coding.jpg
+- name: 小说
+  slug: novel
+  description: |-
+    在这个世界里,没有朝霞的红,没有苔藓的绿,没有夜来香的黄,没有橡木的棕,也没有深海的蓝。
+    有的只是孩子们张惶不安地丈量世界,换来一声叹息。
+  cover: /images/categories/novel.jpg
+- name: 笔记
+  slug: notes
+  description: |-
+    风萧萧,天寥寥。山隐隐,木叶凋。小楼坐定,理书罢了。
+    灯青茶酽花静声悄,添几行斜书歪字,懒寻甚金缕玉箫。
+  cover: /images/categories/notes.jpg
diff --git a/src/content/friends/index.yml b/src/content/metas/friends.yml
similarity index 73%
rename from src/content/friends/index.yml
rename to src/content/metas/friends.yml
index fe45cd6..d56e224 100644
--- a/src/content/friends/index.yml
+++ b/src/content/metas/friends.yml
@@ -1,74 +1,93 @@
-- website: 80后向前冲
+- slug: 80go
+  website: 80后向前冲
   description: 松鼠哥哥
   homepage: https://www.80-go.com
   poster: /images/links/80-go.com.jpg
-- website: Cynosura
+- slug: cynosura
+  website: Cynosura
   description: Trying to light up the dark
   homepage: https://cynosura.one
   poster: /images/links/cynosura.one.jpg
-- website: EEE.ME
+- slug: eee
+  website: EEE.ME
   description: 途方に暮れて
   homepage: https://eee.me
   poster: /images/links/eee.me.jpg
-- website: kn007的个人博客
+- slug: kn007
+  website: kn007的个人博客
   homepage: https://kn007.net
   poster: /images/links/kn007.net.jpg
-- website: Xinsenz茶话
+- slug: xinsenz
+  website: Xinsenz茶话
   description: 树下呷茶,酒好花新。
   homepage: https://xinsenz.com
   poster: /images/links/xinsenz.com.jpg
-- website: 刀客
+- slug: mboker
+  website: 刀客
   description: 这世界需要更多英雄
   homepage: https://blog.mboker.cn
   poster: /images/links/mboker.cn.jpg
-- website: 品味苏州
+- slug: pwsz
+  website: 品味苏州
   description: 吴侬软语、小桥流水的生活点滴
   homepage: https://pwsz.com
   poster: /images/links/pwsz.com.jpg
-- website: 夜枫
+- slug: yefengs
+  website: 夜枫
   homepage: https://yefengs.com
   poster: /images/links/yefengs.com.jpg
-- website: 樱花烂漫
+- slug: minagi
+  website: 樱花烂漫
   description: 樱花烂漫
   homepage: https://minagi.me
   poster: /images/links/minagi.me.jpg
-- website: 羽忆江南
+- slug: yyjn
+  website: 羽忆江南
   description: 烟雨红尘的寻觅,诗画江南的惦记。
   homepage: https://yyjn.org
   poster: /images/links/yyjn.org.jpg
-- website: 行者自若
+- slug: alexinea
+  website: 行者自若
   description: 茶盐观瑟丶行者自若
   homepage: https://alexinea.com
   poster: /images/links/alexinea.com.jpg
-- website: 贾顺名
+- slug: jiasm
+  website: 贾顺名
   description: 全沾码农的一些笔记
   homepage: https://jiasm.github.io
   poster: /images/links/jiasm.github.io.jpg
-- website: 白丁轶事
+- slug: fmoran
+  website: 白丁轶事
   description: Everything should be hurry.
   homepage: https://fmoran.me
   poster: /images/links/fmoran.me.jpg
-- website: 船长の部落格
+- slug: captainofphb
+  website: 船长の部落格
   description: 船长の部落格,记录有趣的事,分享技术经验。
   homepage: https://captainofphb.me
   poster: /images/links/captainofphb.me.jpg
-- website: 小萌博客
+- slug: luoli
+  website: 小萌博客
   description: 互联网分享笔记
   homepage: https://blog.luoli.net
   poster: /images/links/luoli.net.jpg
-- website: LongLuo's Life Notes
+- slug: longluo
+  website: LongLuo's Life Notes
   description: 每一天都是奇迹
   homepage: https://www.longluo.me
   poster: /images/links/longluo.me.jpg
-- website: 佛爷小窝
+- slug: lafoyer
+  website: 佛爷小窝
   description: 一个基于内容分享,创作与灵感结合的折腾笔记博客。
   homepage: https://www.lafoyer.com
   poster: /images/links/lafoyer.com.jpg
-- website: 白熊阿丸的小屋
-  description: 在这里可以看到一个真实的我,我会在这里书写我的一切
+- slug: bxaw
+  website: 白熊阿丸的小屋
+  description: 在这里可以看到一个真实的我,我会在这里书写我的一切。
   homepage: https://bxaw.name
   poster: /images/links/blog.bxaw.name.jpg
-- website: 蒙需
+- slug: jiangcl
+  website: 蒙需
   description: 我的朋友圈
   homepage: https://jiangcl.com
   poster: /images/links/jiangcl.com.jpg
diff --git a/src/content/tags/index.yml b/src/content/metas/tags.yml
similarity index 100%
rename from src/content/tags/index.yml
rename to src/content/metas/tags.yml
diff --git a/src/helpers/schema.ts b/src/helpers/schema.ts
index fb0dc15..ad79b23 100644
--- a/src/helpers/schema.ts
+++ b/src/helpers/schema.ts
@@ -1,7 +1,7 @@
 import { defaultCover } from '@/content.config';
 import type { Image } from '@/helpers/images';
 import options from '@/options';
-import { getCollection, getEntry, render, type RenderResult } from 'astro:content';
+import { getCollection, render, type RenderResult } from 'astro:content';
 import { pinyin } from 'pinyin-pro';
 
 // Import the collections from the astro content.
@@ -18,7 +18,7 @@ export type Category = Omit<(typeof categoriesCollection)[number]['data'], 'cove
   counts: number;
   permalink: string;
 };
-export type Friend = (typeof friendsCollection)[number]['data'][number];
+export type Friend = (typeof friendsCollection)[number]['data'];
 export type Page = Omit<(typeof pagesCollection)[number]['data'], 'cover'> & {
   cover: Image;
   slug: string;
@@ -32,10 +32,20 @@ export type Post = Omit<(typeof postsCollection)[number]['data'], 'cover'> & {
   render: () => Promise<RenderResult>;
   raw: () => Promise<string | undefined>;
 };
-export type Tag = (typeof tagsCollection)[number]['data'][number] & { counts: number; permalink: string };
+export type Tag = (typeof tagsCollection)[number]['data'] & { counts: number; permalink: string };
+
+// Expose this help method for finding the images without null check.
+const images: Array<Image & { id: string }> = imagesCollection.map((image) => ({ id: image.id, ...image.data }));
+export const getImage = (src: string): Image => {
+  const image = images.find((image) => image.id === src);
+  if (image === undefined) {
+    throw new Error(`The image ${src} doesn't exist on public directory`);
+  }
+  return image;
+};
 
 // Translate the Astro content into the original content for dealing with different configuration types.
-export const friends: Friend[] = friendsCollection.flatMap((friends) => friends.data);
+export const friends: Friend[] = friendsCollection.map((friends) => friends.data);
 
 // Override the website for local debugging
 export const pages: Page[] = await Promise.all(
@@ -43,10 +53,10 @@ export const pages: Page[] = await Promise.all(
     .filter((page) => page.data.published || !options.isProd())
     .map(async (page) => ({
       ...page.data,
-      cover: (await getEntry('images', page.data.cover)).data,
+      cover: getImage(page.data.cover),
       slug: page.id,
       permalink: `/${page.id}`,
-      render: async () => await render(await getEntry('pages', page.id)),
+      render: async () => await render(page),
     })),
 );
 export const posts: Post[] = (
@@ -55,13 +65,12 @@ export const posts: Post[] = (
       .filter((post) => post.data.published || !options.isProd())
       .map(async (post) => ({
         ...post.data,
-        cover: (await getEntry('images', post.data.cover)).data,
+        cover: getImage(post.data.cover),
         slug: post.id,
         permalink: `/posts/${post.id}`,
-        render: async () => await render(await getEntry('posts', post.id)),
+        render: async () => await render(post),
         raw: async () => {
-          const entry = await getEntry('posts', post.id);
-          return entry.body;
+          return post.body;
         },
       })),
   )
@@ -73,18 +82,16 @@ export const posts: Post[] = (
 export const categories: Category[] = await Promise.all(
   categoriesCollection.map(async (cat) => ({
     ...cat.data,
-    cover: (await getEntry('images', cat.data.cover)).data,
+    cover: getImage(cat.data.cover),
     counts: posts.filter((post) => post.category === cat.data.name).length,
     permalink: `/cats/${cat.data.slug}`,
   })),
 );
-export const tags: Tag[] = tagsCollection.flatMap((tags) => {
-  return tags.data.map((tag) => ({
-    counts: posts.filter((post) => post.tags.includes(tag.name)).length,
-    permalink: `/tags/${tag.slug}`,
-    ...tag,
-  }));
-});
+export const tags: Tag[] = tagsCollection.map((tag) => ({
+  ...tag.data,
+  counts: posts.filter((post) => post.tags.includes(tag.data.name)).length,
+  permalink: `/tags/${tag.data.slug}`,
+}));
 
 // Find the missing categories from posts.
 const missingCategories: string[] = posts