summaryrefslogtreecommitdiff
path: root/src/pages/outbox.json.ts
blob: 64b0b1890e41f93734af2a9230923a22a8f4a4bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import type { APIRoute } from "astro";
import { env } from "../lib/environment.ts";
import {
  fromPosts,
  isOriginal,
  isTranslation,
  sortFirstCreated,
} from "../lib/collection/helpers.ts";
import { getCollection } from "astro:content";
import { Original, Translation } from "../lib/collection/schemas.ts";
import { defined } from "../utils/anonymous.ts";

const { PUBLIC_SITE_URL } = env;
const site = new URL(PUBLIC_SITE_URL);

export const GET: APIRoute = async (): Promise<Response> => {
  const collection = await getCollection("blog");
  const orderedItems = collection.map(({ id, data, rendered }) => {
    const original = Original.safeParse(data);
    if (original.success) {
      const { dateCreated, title } = original.data;
      return {
        id: new URL(`blog/read/${id}`, site).href,
        type: "Create",
        actor: new URL("actor.json", site).href,
        published: dateCreated.toISOString(),
        to: ["https://www.w3.org/ns/activitystreams#Public"],
        object: {
          id: new URL(`blog/read/${id}`, site).href,
          type: "Article",
          name: title,
          url: new URL(`blog/read/${id}`, site).href,
          content: rendered?.html ?? "",
          alternate: collection.filter(isTranslation).map(({ id, data }) => {
            const { lang } = data;
            return {
              "type": "Link",
              href: new URL(`blog/read/${id}`, site).href,
              "hreflang": lang,
            };
          }),
        },
      };
    }
    const translation = Translation.safeParse(data);
    if (translation.success) {
      const { dateCreated, title, translationOf } = translation.data;
      return {
        id: new URL(`blog/read/${id}`, site).href,
        type: "Create",
        actor: new URL("actor.json", site).href,
        published: dateCreated.toISOString(),
        to: ["https://www.w3.org/ns/activitystreams#Public"],
        object: {
          id: new URL(`blog/read/${id}`, site).href,
          type: "Article",
          name: title,
          url: new URL(`blog/read/${id}`, site).href,
          content: rendered?.html ?? "",
          inReplyTo: new URL(`blog/read/${translationOf.id}`, site).href,
        },
      };
    }
    const micro = Translation.safeParse(data);
    if (micro.success) {
      const { dateCreated, title } = micro.data;
      return {
        id: new URL(`blog/read/${id}`, site).href,
        type: "Create",
        actor: new URL("actor.json", site).href,
        published: dateCreated.toISOString(),
        to: ["https://www.w3.org/ns/activitystreams#Public"],
        object: {
          id: new URL(`blog/read/${id}`, site).href,
          type: "Note",
          name: title,
          url: new URL(`blog/read/${id}`, site).href,
          content: rendered?.html ?? "",
        },
      };
    }
    return undefined;
  }).filter(defined).sort((a, b) =>
    new Date(a.published).getTime() - new Date(b.published).getTime()
  );
  const outbox = {
    "@context": "https://www.w3.org/ns/activitystreams",
    id: new URL("outbox.json", site).href,
    type: "OrderedCollection",
    totalItems: orderedItems.length,
    orderedItems,
  };
  return new Response(JSON.stringify(outbox), {
    headers: { "Content-Type": "application/activity+json" },
  });
};