@rmdes/indiekit-endpoint-activitypub 3.10.2 → 3.10.3

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 +39 -18
  2. package/package.json +1 -1
package/lib/syndicator.js CHANGED
@@ -290,49 +290,70 @@ export function createSyndicator(plugin) {
290
290
  // ─── Timeline helpers ───────────────────────────────────────────────────────
291
291
 
292
292
  /**
293
- * Build content from JF2 properties. Synthesizes content for interaction
294
- * types (likes, bookmarks, reposts) that have no body text.
293
+ * Build content from JF2 properties for the ap_timeline entry.
294
+ * For interaction types (likes, bookmarks, reposts), always includes
295
+ * the target URL — even when there's comment text alongside it.
295
296
  */
296
297
  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
- };
298
+ const esc = (s) => String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
299
+
300
+ // Extract any existing body content
301
+ const raw = properties.content;
302
+ let bodyText = "";
303
+ let bodyHtml = "";
304
+ if (raw) {
305
+ if (typeof raw === "string") {
306
+ bodyText = raw;
307
+ bodyHtml = `<p>${raw}</p>`;
308
+ } else {
309
+ bodyText = raw.text || raw.value || "";
310
+ bodyHtml = raw.html || raw.text || raw.value || "";
305
311
  }
306
312
  }
307
313
 
308
- // Synthesize for interaction types
309
- const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
314
+ // Interaction types: prepend label + target URL, append any comment
310
315
  const likeOf = properties["like-of"];
311
316
  if (likeOf) {
317
+ const prefix = `Liked: ${likeOf}`;
318
+ const prefixHtml = `<p>Liked: <a href="${esc(likeOf)}">${esc(likeOf)}</a></p>`;
312
319
  return {
313
- text: `Liked: ${likeOf}`,
314
- html: `<p>Liked: <a href="${esc(likeOf)}">${esc(likeOf)}</a></p>`,
320
+ text: bodyText ? `${prefix}\n\n${bodyText}` : prefix,
321
+ html: bodyText ? `${prefixHtml}\n${bodyHtml}` : prefixHtml,
315
322
  };
316
323
  }
324
+
317
325
  const bookmarkOf = properties["bookmark-of"];
318
326
  if (bookmarkOf) {
319
327
  const label = properties.name || bookmarkOf;
328
+ const prefix = `Bookmarked: ${label}`;
329
+ const prefixHtml = `<p>Bookmarked: <a href="${esc(bookmarkOf)}">${esc(label)}</a></p>`;
320
330
  return {
321
- text: `Bookmarked: ${label}`,
322
- html: `<p>Bookmarked: <a href="${esc(bookmarkOf)}">${esc(label)}</a></p>`,
331
+ text: bodyText ? `${prefix}\n\n${bodyText}` : prefix,
332
+ html: bodyText ? `${prefixHtml}\n${bodyHtml}` : prefixHtml,
323
333
  };
324
334
  }
335
+
325
336
  const repostOf = properties["repost-of"];
326
337
  if (repostOf) {
327
338
  const label = properties.name || repostOf;
339
+ const prefix = `Reposted: ${label}`;
340
+ const prefixHtml = `<p>Reposted: <a href="${esc(repostOf)}">${esc(label)}</a></p>`;
328
341
  return {
329
- text: `Reposted: ${label}`,
330
- html: `<p>Reposted: <a href="${esc(repostOf)}">${esc(label)}</a></p>`,
342
+ text: bodyText ? `${prefix}\n\n${bodyText}` : prefix,
343
+ html: bodyText ? `${prefixHtml}\n${bodyHtml}` : prefixHtml,
331
344
  };
332
345
  }
346
+
347
+ // Regular post — return body content as-is
348
+ if (bodyText || bodyHtml) {
349
+ return { text: bodyText, html: bodyHtml };
350
+ }
351
+
352
+ // Article with title but no body
333
353
  if (properties.name) {
334
354
  return { text: properties.name, html: `<p>${esc(properties.name)}</p>` };
335
355
  }
356
+
336
357
  return { text: "", html: "" };
337
358
  }
338
359
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-activitypub",
3
- "version": "3.10.2",
3
+ "version": "3.10.3",
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",