import { getApIds } from "./type.js"; import Resolver from "./resolver.js"; import { resolvePerson } from "./models/person.js"; import { unique, concat } from "../../prelude/array.js"; import promiseLimit from "promise-limit"; import { RecursionLimiter } from "../../models/repositories/user-profile.js"; export async function parseAudience(actor, to, cc, resolver, limiter = new RecursionLimiter()) { const toGroups = groupingAudience(getApIds(to), actor); const ccGroups = groupingAudience(getApIds(cc), actor); const others = unique(concat([ toGroups.other, ccGroups.other ])); resolver ??= new Resolver(); const limit = promiseLimit(2); const mentionedUsers = (await Promise.all(others.map((id)=>limit(()=>resolvePerson(id, resolver, limiter).catch(()=>null))))).filter((x)=>x != null); if (toGroups.public.length > 0) { return { visibility: "public", mentionedUsers, visibleUsers: [] }; } if (ccGroups.public.length > 0) { return { visibility: "home", mentionedUsers, visibleUsers: [] }; } if (toGroups.followers.length > 0) { return { visibility: "followers", mentionedUsers, visibleUsers: [] }; } return { visibility: "specified", mentionedUsers, visibleUsers: mentionedUsers }; } function groupingAudience(ids, actor) { const groups = { public: [], followers: [], other: [] }; for (const id of ids){ if (isPublic(id)) { groups.public.push(id); } else if (isFollowers(id, actor)) { groups.followers.push(id); } else { groups.other.push(id); } } groups.other = unique(groups.other); return groups; } function isPublic(id) { return [ "https://www.w3.org/ns/activitystreams#Public", "as:Public", "Public" ].includes(id); } function isFollowers(id, actor) { return id === (actor.followersUri || `${actor.uri}/followers`); }