activitypress/src/outbox.ts

81 lines
2.5 KiB
TypeScript

import db from "./db.js";
import { z } from "zod";
import { get as getUserByNickname } from "./user.js";
import { fillRoute } from "./router.js";
import { getByUserId as getArticlesByUserId, getById as getArticleById, Article } from "./article.js";
import { createArticleActivity, deleteArticleActivity } from "./activity.js";
import { orderedCollection } from "./collection.js";
export const zRawOutboxRecord = z.object({
id: z.number().min(0),
users_id: z.number().min(0),
verb: z.string().regex(/^[a-zA-Z]+$/).min(1),
articles_id: z.number().min(0),
created_at: z.date(),
updated_at: z.union([z.date(), z.null()]),
slug: z.optional(z.string()),
file: z.optional(z.string()),
title: z.optional(z.string())
});
export type RawOutboxRecord = z.infer<typeof zRawOutboxRecord>;
export const toCollection = async (nickname: string): Promise<Record<string, any> | null> => {
const user = await getUserByNickname(nickname);
if (user) {
const articles = await get(user.id)
const activities = articles.map((a) => {
if (a.verb === "Create") {
return createArticleActivity(a, user);
}
else if (a.verb === "Delete") {
return deleteArticleActivity(a, user);
}
else {
throw "unexpected verb";
}
});
const collection = orderedCollection(fillRoute("outbox", user.nickname), activities);
return collection;
}
else {
return null;
}
};
export const add = async (articleId: number): Promise<number> => {
const article = await getArticleById(articleId);
if (article) {
return await db("outboxes").insert({
users_id: article.id,
verb: "Create",
articles_id: articleId,
created_at: article.created_at
})
.returning("id")
.then(([{ id: id }]: { id: number }[]) => id)
}
else throw "failed to add to outbox";
};
interface ArticleActivity extends Article {
verb: string;
activity_created_at: Date | number;
}
export const get = async (userId: number): Promise<ArticleActivity[]> =>
db<ArticleActivity>("articles")
.select("articles.*", "outboxes.verb", "outboxes.created_at as activity_created_at")
.join("outboxes", "articles.id", "outboxes.articles_id")
.where("articles.users_id", userId)
.whereIn("outboxes.verb", ["Create", "Delete"])
.orderBy("outboxes.created_at", "desc")
;