@rmdes/indiekit-endpoint-activitypub 3.13.7 → 3.13.8

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/jf2-to-as2.js +26 -4
  2. package/package.json +4 -1
package/lib/jf2-to-as2.js CHANGED
@@ -540,10 +540,12 @@ function buildPlainTags(properties, publicationUrl, existing) {
540
540
  const tags = [...(existing || [])];
541
541
  if (properties.category) {
542
542
  for (const cat of asArray(properties.category)) {
543
+ const value = categoryString(cat);
544
+ if (!value) continue;
543
545
  tags.push({
544
546
  type: "Hashtag",
545
- name: `#${cat.split("/").at(-1).replace(/\s+/g, "")}`,
546
- href: `${publicationUrl}categories/${encodeURIComponent(cat)}`,
547
+ name: `#${value.split("/").at(-1).replace(/\s+/g, "")}`,
548
+ href: `${publicationUrl}categories/${encodeURIComponent(value)}`,
547
549
  });
548
550
  }
549
551
  }
@@ -562,11 +564,13 @@ function buildFedifyTags(properties, publicationUrl, postType) {
562
564
  }
563
565
  if (properties.category) {
564
566
  for (const cat of asArray(properties.category)) {
567
+ const value = categoryString(cat);
568
+ if (!value) continue;
565
569
  tags.push(
566
570
  new Hashtag({
567
- name: `#${cat.split("/").at(-1).replace(/\s+/g, "")}`,
571
+ name: `#${value.split("/").at(-1).replace(/\s+/g, "")}`,
568
572
  href: new URL(
569
- `${publicationUrl}categories/${encodeURIComponent(cat)}`,
573
+ `${publicationUrl}categories/${encodeURIComponent(value)}`,
570
574
  ),
571
575
  }),
572
576
  );
@@ -583,6 +587,24 @@ function asArray(value) {
583
587
  return Array.isArray(value) ? value : [value];
584
588
  }
585
589
 
590
+ /**
591
+ * Coerce a JF2 `category` entry to a hashtag-safe string, or null if it is not
592
+ * a plain tag.
593
+ *
594
+ * A Microformats/JF2 `category` array can legitimately contain non-strings —
595
+ * most commonly an IndieWeb person-tag (a nested h-card object), but malformed
596
+ * data can also yield null/number. Those are NOT hashtags. Returning null lets
597
+ * the tag builders skip them instead of crashing on `cat.split` (regression
598
+ * fixed 2026-06-06: "cat.split is not a function" broke ActivityPub syndication
599
+ * of any post carrying a person-tag).
600
+ *
601
+ * @param {unknown} cat
602
+ * @returns {string|null}
603
+ */
604
+ function categoryString(cat) {
605
+ return typeof cat === "string" && cat.trim() !== "" ? cat : null;
606
+ }
607
+
586
608
  function guessMediaType(url) {
587
609
  const ext = url.split(".").pop()?.toLowerCase();
588
610
  const types = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-activitypub",
3
- "version": "3.13.7",
3
+ "version": "3.13.8",
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",
@@ -22,6 +22,9 @@
22
22
  "type": "module",
23
23
  "main": "index.js",
24
24
  "exports": "./index.js",
25
+ "scripts": {
26
+ "test": "node --test tests/*.test.js"
27
+ },
25
28
  "files": [
26
29
  "assets",
27
30
  "lib",