server/utils/timelines.ts

73 lines
2.5 KiB
TypeScript
Raw Normal View History

2024-04-08 05:28:18 +02:00
import type { Status, User, Prisma, Notification } from "@prisma/client";
2024-04-08 04:24:18 +02:00
2024-04-08 05:28:18 +02:00
export async function fetchTimeline<T extends User | Status | Notification>(
model:
| Prisma.StatusDelegate
| Prisma.UserDelegate
| Prisma.NotificationDelegate,
args:
| Prisma.StatusFindManyArgs
| Prisma.UserFindManyArgs
| Prisma.NotificationFindManyArgs,
2024-04-08 04:24:18 +02:00
req: Request,
) {
2024-04-08 04:32:45 +02:00
// BEFORE: Before in a top-to-bottom order, so the most recent posts
// AFTER: After in a top-to-bottom order, so the oldest posts
2024-04-08 04:24:18 +02:00
// @ts-expect-error This is a hack to get around the fact that Prisma doesn't have a common base type for all models
const objects = (await model.findMany(args)) as T[];
// Constuct HTTP Link header (next and prev) only if there are more statuses
const linkHeader = [];
if (objects.length > 0) {
// Check if there are statuses before the first one
// @ts-expect-error This is a hack to get around the fact that Prisma doesn't have a common base type for all models
const objectsBefore = await model.findMany({
...args,
2024-04-08 04:24:18 +02:00
where: {
...args.where,
2024-04-08 04:24:18 +02:00
id: {
gt: objects[0].id,
},
},
take: 1,
});
if (objectsBefore.length > 0) {
const urlWithoutQuery = req.url.split("?")[0];
// Add prev link
linkHeader.push(
`<${urlWithoutQuery}?min_id=${objects[0].id}>; rel="prev"`,
);
}
if (objects.length < (args.take ?? Number.POSITIVE_INFINITY)) {
// Check if there are statuses after the last one
// @ts-expect-error This is a hack to get around the fact that Prisma doesn't have a common base type for all models
const objectsAfter = await model.findMany({
...args,
2024-04-08 04:24:18 +02:00
where: {
...args.where,
2024-04-08 04:24:18 +02:00
id: {
lt: objects.at(-1)?.id,
},
},
take: 1,
});
if (objectsAfter.length > 0) {
const urlWithoutQuery = req.url.split("?")[0];
// Add next link
linkHeader.push(
2024-04-08 04:32:45 +02:00
`<${urlWithoutQuery}?max_id=${objectsAfter[0].id}>; rel="next"`,
2024-04-08 04:24:18 +02:00
);
}
}
}
return {
link: linkHeader.join(", "),
objects,
};
}