bgenc.net/src/routes/posts/[[page=integer]]/+page.server.ts

50 lines
1.4 KiB
TypeScript

import _ from 'lodash';
import { readingTime } from 'reading-time-estimator';
import path from 'path';
import { readFile } from 'fs/promises';
const PAGE_SIZE = 10;
export async function load({ params }) {
const allPostFiles = import.meta.glob<SvelteAllProps>('/src/routes/posts/*.md');
const iterablePostFiles = Object.entries(allPostFiles);
const markdownFilesPath = path.resolve(
process.env.npm_package_json ? path.dirname(process.env.npm_package_json) : '.',
'src',
'routes',
'posts',
);
const posts = await Promise.all(
iterablePostFiles.map(async ([filePath, resolver]) => {
const { metadata } = await resolver();
const slug = /[/]([^/]*)[.]md$/.exec(filePath)?.[1];
if (!slug) throw new Error(`Could not parse slug from path: ${filePath}`);
const contents = await readFile(path.join(markdownFilesPath, `${slug}.md`), 'utf8');
return {
meta: metadata,
path: slug,
readingTime: readingTime(contents),
};
}),
);
// Get the page number, converting it to a 0-based index
const page = (params.page ? parseInt(params.page, 10) : 1) - 1;
return {
posts: _.reverse(_.sortBy(posts, ({ meta }) => meta.date)).slice(
page * PAGE_SIZE,
(page + 1) * PAGE_SIZE,
),
hasMore: posts.length > (page + 1) * PAGE_SIZE,
page: page + 1,
pageCount: Math.ceil(posts.length / PAGE_SIZE),
};
}
export type Post = Awaited<ReturnType<typeof load>>['posts'][number];