@rmdes/indiekit-endpoint-activitypub 3.10.1 → 3.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/syndicator.js +46 -8
  2. package/package.json +1 -1
package/lib/syndicator.js CHANGED
@@ -224,7 +224,7 @@ export function createSyndicator(plugin) {
224
224
  // timelines (Phanpy/Moshidon). Uses $setOnInsert — idempotent.
225
225
  try {
226
226
  const profile = await plugin._collections.ap_profile?.findOne({});
227
- const content = normalizeContent(properties.content);
227
+ const content = buildTimelineContent(properties);
228
228
  const timelineItem = {
229
229
  uid: properties.url,
230
230
  url: properties.url,
@@ -289,13 +289,51 @@ export function createSyndicator(plugin) {
289
289
 
290
290
  // ─── Timeline helpers ───────────────────────────────────────────────────────
291
291
 
292
- function normalizeContent(content) {
293
- if (!content) return { text: "", html: "" };
294
- if (typeof content === "string") return { text: content, html: `<p>${content}</p>` };
295
- return {
296
- text: content.text || content.value || "",
297
- html: content.html || content.text || content.value || "",
298
- };
292
+ /**
293
+ * Build content from JF2 properties. Synthesizes content for interaction
294
+ * types (likes, bookmarks, reposts) that have no body text.
295
+ */
296
+ function buildTimelineContent(properties) {
297
+ const content = properties.content;
298
+ if (content) {
299
+ if (typeof content === "string") return { text: content, html: `<p>${content}</p>` };
300
+ if (content.text || content.html) {
301
+ return {
302
+ text: content.text || content.value || "",
303
+ html: content.html || content.text || content.value || "",
304
+ };
305
+ }
306
+ }
307
+
308
+ // Synthesize for interaction types
309
+ const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
310
+ const likeOf = properties["like-of"];
311
+ if (likeOf) {
312
+ return {
313
+ text: `Liked: ${likeOf}`,
314
+ html: `<p>Liked: <a href="${esc(likeOf)}">${esc(likeOf)}</a></p>`,
315
+ };
316
+ }
317
+ const bookmarkOf = properties["bookmark-of"];
318
+ if (bookmarkOf) {
319
+ const label = properties.name || bookmarkOf;
320
+ return {
321
+ text: `Bookmarked: ${label}`,
322
+ html: `<p>Bookmarked: <a href="${esc(bookmarkOf)}">${esc(label)}</a></p>`,
323
+ };
324
+ }
325
+ const repostOf = properties["repost-of"];
326
+ if (repostOf) {
327
+ const label = properties.name || repostOf;
328
+ return {
329
+ text: `Reposted: ${label}`,
330
+ html: `<p>Reposted: <a href="${esc(repostOf)}">${esc(label)}</a></p>`,
331
+ };
332
+ }
333
+ if (properties.name) {
334
+ return { text: properties.name, html: `<p>${esc(properties.name)}</p>` };
335
+ }
336
+ return { text: "", html: "" };
299
337
  }
300
338
 
301
339
  function mapPostType(postType) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-activitypub",
3
- "version": "3.10.1",
3
+ "version": "3.10.2",
4
4
  "description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
5
5
  "keywords": [
6
6
  "indiekit",