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; raw: () => Promise; }; -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 = 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