book-catalog.ts 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. import { promises as fs } from "fs";
  2. import path from "path";
  3. import { demoBooks } from "@/data/demo-books";
  4. import { Book } from "@/types/book";
  5. export { getBookEntries, getBookContentCount, getBookStructureStats } from "@/lib/book-helpers";
  6. const storageCatalogPath = path.join(process.cwd(), "storage", "books", "catalog.json");
  7. function normalizeBooks(books: Book[]) {
  8. return books
  9. .map((book) => ({
  10. ...book,
  11. sections: [...book.sections]
  12. .sort((a, b) => a.order - b.order)
  13. .map((section) => ({
  14. ...section,
  15. entries: [...section.entries].sort((a, b) => a.order - b.order)
  16. }))
  17. }))
  18. .sort((a, b) => a.title.localeCompare(b.title, "zh-CN"));
  19. }
  20. export async function getBooks() {
  21. try {
  22. const raw = await fs.readFile(storageCatalogPath, "utf8");
  23. const parsed = JSON.parse(raw) as Book[];
  24. if (Array.isArray(parsed) && parsed.length > 0) {
  25. return normalizeBooks(parsed);
  26. }
  27. } catch {
  28. // Fall back to bundled demo books when no formal catalog exists yet.
  29. }
  30. return normalizeBooks(demoBooks);
  31. }
  32. export async function getBookById(bookId: string) {
  33. const books = await getBooks();
  34. return books.find((book) => book.id === bookId);
  35. }