import { ACTIVITY_INBOX_PATH, ACTIVITY_OUTBOX_PATH, ACTIVITY_PATH, ACTOR, BASE_URL, DATA_PATH, POSTS_PATH } from "./env"; import path from "path" import { readdir } from "fs/promises" import { unlinkSync } from "node:fs" const matter = require('gray-matter') export async function doActivity(activity:any, object_id:string|null|undefined) { if(activity.type === "Create" && activity.object) { if(!object_id) object_id = new Date(activity.object.published).getTime().toString(16) const file = Bun.file(path.join(POSTS_PATH, `${object_id}.md`)) const { content, published, id, attributedTo } = activity.object //TODO: add appropriate content for different types (e.g. like-of, etc) await Bun.write(file, matter.stringify(content || "", { id, published, attributedTo })) const activityFile = Bun.file(path.join(ACTIVITY_PATH, `${object_id}.activity.json`)) await Bun.write(activityFile, JSON.stringify(activity)) } } export async function createInboxActivity(activity:any, object_id:any) { const activityFile = Bun.file(path.join(ACTIVITY_INBOX_PATH, `${object_id}.activity.json`)) await Bun.write(activityFile, JSON.stringify(activity)) } export async function createOutboxActivity(activity:any, object_id:any) { const activityFile = Bun.file(path.join(ACTIVITY_OUTBOX_PATH, `${object_id}.activity.json`)) await Bun.write(activityFile, JSON.stringify(activity)) } export async function getInboxActivity(id:string) { const file = Bun.file(path.join(ACTIVITY_INBOX_PATH, `${id}.activity.json`)) return await file.json() } export async function getOutboxActivity(id:string) { const file = Bun.file(path.join(ACTIVITY_OUTBOX_PATH, `${id}.activity.json`)) return await file.json() } export async function listInboxActivities() { return await Promise.all( (await readdir(ACTIVITY_INBOX_PATH)).filter(v => v.endsWith('.activity.json')) .map(async filename => await Bun.file(path.join(ACTIVITY_INBOX_PATH, filename)).json()) ) } export async function listOutboxActivities() { return await Promise.all( (await readdir(ACTIVITY_OUTBOX_PATH)).filter(v => v.endsWith('.activity.json')) .map(async filename => await Bun.file(path.join(ACTIVITY_OUTBOX_PATH, filename)).json()) ) } export async function createPost(post_object:any, object_id:string) { const file = Bun.file(path.join(POSTS_PATH, `${object_id}.md`)) const {type, object} = post_object if(object){ let { content, published, id, attributedTo } = object if(content as string) content = '> ' + content.replace('\n', '\n> ') + '\n' else content = "" content += post_object.content || "" //TODO: add appropriate content for different types (e.g. like, etc) await Bun.write(file, matter.stringify(content, { id, published, attributedTo, type })) } else { const { content, published, id, attributedTo } = post_object await Bun.write(file, matter.stringify(content || "", { id, published, attributedTo, type })) } } export async function getPost(id:string) { const file = Bun.file(path.join(POSTS_PATH, `${id}.md`)) const { data, content } = matter(await file.text()) return { ...data, content: content.trim() } } export async function deletePost(id:string) { unlinkSync(path.join(POSTS_PATH, id + '.md')) } export async function listPosts() { return await Promise.all((await readdir(POSTS_PATH)).filter(v => v.endsWith('.md')).map(async filename => await getPost(filename.slice(0, -3)))) } export async function getActivity(id:string) { const file = Bun.file(path.join(ACTIVITY_PATH, `${id}.activity.json`)) return await file.json() } export async function createFollowing(handle:string, id:string) { const file = Bun.file(path.join(DATA_PATH, `following.json`)) const following_list = await file.json() as Array if(!following_list.find(v => v.id === id || v.handle === handle)) following_list.push({id, handle, createdAt: new Date().toISOString()}) await Bun.write(file, JSON.stringify(following_list)) } export async function deleteFollowing(handle:string) { const file = Bun.file(path.join(DATA_PATH, `following.json`)) const following_list = await file.json() as Array await Bun.write(file, JSON.stringify(following_list.filter(v => v.handle !== handle))) } export async function getFollowing(handle:string) { const file = Bun.file(path.join(DATA_PATH, `following.json`)) const following_list = await file.json() as Array return following_list.find(v => v.handle === handle) } export async function listFollowing(onlyAccepted = true) { const file = Bun.file(path.join(DATA_PATH, `following.json`)) return ((await file.json()) as Array).filter(f => !onlyAccepted || f.accepted) } export async function acceptFollowing(handle:string) { const file = Bun.file(path.join(DATA_PATH, `following.json`)) const following_list = await file.json() as Array const following = following_list.find(v => v.handle === handle) if(following) following.accepted = new Date().toISOString() await Bun.write(file, JSON.stringify(following_list)) } export async function createFollower(actor:string, id:string) { const file = Bun.file(path.join(DATA_PATH, `followers.json`)) const followers_list = await file.json() as Array if(!followers_list.find(v => v.id === id || v.actor === actor)) followers_list.push({id, actor, createdAt: new Date().toISOString()}) await Bun.write(file, JSON.stringify(followers_list)) } export async function deleteFollower(actor:string) { const file = Bun.file(path.join(DATA_PATH, `followers.json`)) const followers_list = await file.json() as Array await Bun.write(file, JSON.stringify(followers_list.filter(v => v.actor !== actor))) } export async function getFollower(actor:string) { const file = Bun.file(path.join(DATA_PATH, `followers.json`)) const followers_list = await file.json() as Array return followers_list.find(v => v.actor === actor) } export async function listFollowers() { const file = Bun.file(path.join(DATA_PATH, `followers.json`)) return await file.json() as Array } export async function createLiked(object_id:string, id:string) { const file = Bun.file(path.join(DATA_PATH, `liked.json`)) const liked_list = await file.json() as Array if(!liked_list.find(v => v.object_id === object_id)) liked_list.push({id, object_id, createdAt: new Date().toISOString()}) await Bun.write(file, JSON.stringify(liked_list)) } export async function deleteLiked(object_id:string) { const file = Bun.file(path.join(DATA_PATH, `liked.json`)) const liked_list = await file.json() as Array await Bun.write(file, JSON.stringify(liked_list.filter(v => v.object_id !== object_id))) } export async function listLiked() { const file = Bun.file(path.join(DATA_PATH, `liked.json`)) return await file.json() as Array }