2024-04-13 14:20:12 +02:00
|
|
|
import { config } from "config-manager";
|
2024-04-11 14:12:16 +02:00
|
|
|
import type {
|
|
|
|
|
Notification,
|
2024-04-13 14:20:12 +02:00
|
|
|
findManyNotifications,
|
2024-04-11 14:12:16 +02:00
|
|
|
} from "~database/entities/Notification";
|
2024-04-17 06:09:21 +02:00
|
|
|
import type { Status, findManyNotes } from "~database/entities/Status";
|
2024-04-25 05:40:27 +02:00
|
|
|
import type { UserType, findManyUsers } from "~database/entities/User";
|
2024-04-11 13:39:07 +02:00
|
|
|
import type { db } from "~drizzle/db";
|
2024-04-08 04:24:18 +02:00
|
|
|
|
2024-04-25 05:40:27 +02:00
|
|
|
export async function fetchTimeline<T extends UserType | Status | Notification>(
|
2024-04-08 05:28:18 +02:00
|
|
|
model:
|
2024-04-17 06:09:21 +02:00
|
|
|
| typeof findManyNotes
|
2024-04-11 13:39:07 +02:00
|
|
|
| typeof findManyUsers
|
2024-04-11 14:12:16 +02:00
|
|
|
| typeof findManyNotifications,
|
2024-04-08 05:28:18 +02:00
|
|
|
args:
|
2024-04-17 06:09:21 +02:00
|
|
|
| Parameters<typeof findManyNotes>[0]
|
2024-04-11 13:39:07 +02:00
|
|
|
| Parameters<typeof findManyUsers>[0]
|
2024-04-17 08:36:01 +02:00
|
|
|
| Parameters<typeof db.query.Notifications.findMany>[0],
|
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
|
2024-04-11 13:39:07 +02:00
|
|
|
const objects = (await model(args)) as T[];
|
2024-04-08 04:24:18 +02:00
|
|
|
|
|
|
|
|
// Constuct HTTP Link header (next and prev) only if there are more statuses
|
|
|
|
|
const linkHeader = [];
|
2024-04-11 16:01:12 +02:00
|
|
|
const urlWithoutQuery = new URL(
|
|
|
|
|
new URL(req.url).pathname,
|
|
|
|
|
config.http.base_url,
|
|
|
|
|
).toString();
|
2024-04-08 04:24:18 +02:00
|
|
|
|
|
|
|
|
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
|
2024-04-11 13:39:07 +02:00
|
|
|
const objectsBefore = await model({
|
2024-04-08 04:36:14 +02:00
|
|
|
...args,
|
2024-04-11 13:39:07 +02:00
|
|
|
// @ts-expect-error this hack breaks typing :(
|
|
|
|
|
where: (object, { gt }) => gt(object.id, objects[0].id),
|
|
|
|
|
limit: 1,
|
2024-04-08 04:24:18 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (objectsBefore.length > 0) {
|
|
|
|
|
// Add prev link
|
|
|
|
|
linkHeader.push(
|
2024-04-11 15:52:44 +02:00
|
|
|
`<${urlWithoutQuery}?limit=${args?.limit ?? 20}&min_id=${
|
|
|
|
|
objects[0].id
|
|
|
|
|
}>; rel="prev"`,
|
2024-04-08 04:24:18 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-11 15:52:44 +02:00
|
|
|
if (objects.length >= (Number(args?.limit) ?? 20)) {
|
2024-04-08 04:24:18 +02:00
|
|
|
// Check if there are statuses after the last one
|
2024-04-11 13:39:07 +02:00
|
|
|
// @ts-expect-error hack again
|
|
|
|
|
const objectsAfter = await model({
|
2024-04-08 04:36:14 +02:00
|
|
|
...args,
|
2024-04-11 13:39:07 +02:00
|
|
|
// @ts-expect-error this hack breaks typing :(
|
|
|
|
|
where: (object, { lt }) => lt(object.id, objects.at(-1).id),
|
|
|
|
|
limit: 1,
|
2024-04-08 04:24:18 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (objectsAfter.length > 0) {
|
|
|
|
|
// Add next link
|
|
|
|
|
linkHeader.push(
|
2024-04-11 15:52:44 +02:00
|
|
|
`<${urlWithoutQuery}?limit=${args?.limit ?? 20}&max_id=${
|
|
|
|
|
objects.at(-1)?.id
|
|
|
|
|
}>; rel="next"`,
|
2024-04-08 04:24:18 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
link: linkHeader.join(", "),
|
|
|
|
|
objects,
|
|
|
|
|
};
|
|
|
|
|
}
|