import fs from "node:fs" import path from "node:path" /** * 微信读书「最近在读」的数据读取与展示格式化。 * * 数据由 `scripts/fetch-reading.mjs` 在构建前抓到 `src/data/reading.json`, * 这个模块只读文件,不发任何网络请求 —— 页面是纯静态的。 * * 只允许在 `.astro` 的 frontmatter 里用(依赖 node:fs,不能在客户端组件里 import)。 */ export type ReadingBook = { bookId: string title: string author: string /** 微信读书的分类是「大类-子类」复合串,如 `文学-外国文学` */ category: string cover: string /** 0-100 的整数;null 表示这次没取到进度(单本失败) */ progress: number | null finished: boolean /** ISO 字符串 */ lastReadAt: string /** 微信读书的跳转链接,实测是普通 https,浏览器能直接打开 */ deepLink: string } export type ReadingData = { updatedAt: string source: string books: ReadingBook[] } const DATA_FILE = path.join(process.cwd(), "src/data/reading.json") /** 读不到或格式不对时返回 null,调用方按空态处理,不要抛错。 */ export function getReadingData(): ReadingData | null { try { const parsed = JSON.parse(fs.readFileSync(DATA_FILE, "utf-8")) as ReadingData if (!parsed || !Array.isArray(parsed.books)) return null return parsed } catch { return null } } /** * 微信读书的时间戳统一按 `YYYY-MM-DD` 展示(官方 Skill 文档的硬性要求), * 顺带避开「N 天前」这类文案在静态站上会随构建时间变旧的问题。 */ export function formatReadingDate(iso: string | null | undefined): string { if (!iso) return "" const date = new Date(iso) if (Number.isNaN(date.getTime())) return "" return new Intl.DateTimeFormat("en-CA", { timeZone: "Asia/Shanghai", year: "numeric", month: "2-digit", day: "2-digit", }).format(date) }