@singi-labs/sifa-sdk 0.12.24 → 0.12.27

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.
package/dist/index.cjs CHANGED
@@ -1022,6 +1022,12 @@ var APP_CATEGORY_MAP = {
1022
1022
  // Onboard from moll.dev profile audit.
1023
1023
  recipe: "Recipes",
1024
1024
  // exchange.recipe.recipe — authored recipes on recipe.exchange
1025
+ // Onboard from willow.sh profile audit.
1026
+ guestbook: "Social",
1027
+ // dev.baileytownsend.guestbook.entry — a note left on someone's cross-site guestbook
1028
+ // Onboard from trezy.codes profile audit.
1029
+ atmobb: "Social",
1030
+ // app.atmobb.discussion.{thread,reply} — federated forum threads + replies
1025
1031
  // Web-only (rendered in pills/cards via sifa-web atproto-apps.ts;
1026
1032
  // no backend scan collection yet)
1027
1033
  linkat: "Links",
@@ -2289,6 +2295,9 @@ var APP_URL_PATTERNS = Object.freeze({
2289
2295
  profileUrlPattern: "https://grain.social/profile/{did}"
2290
2296
  },
2291
2297
  youandme: { profileUrlPattern: "https://youandme.at" },
2298
+ // atmoBB per-item thread/reply URLs are built bespoke in resolve-card-url.ts
2299
+ // (raw-colon /t/{did}/{rkey}); this is only the member-profile fallback.
2300
+ atmobb: { profileUrlPattern: "https://atmobb.app/members/{did}" },
2292
2301
  // anisota: upgraded with per-record URL pattern below.
2293
2302
  margin: { profileUrlPattern: "https://margin.at" },
2294
2303
  beaconbits: { profileUrlPattern: "https://beaconbits.app" },
@@ -2358,6 +2367,12 @@ var APP_URL_PATTERNS = Object.freeze({
2358
2367
  // record.canonicalUrl (handled in resolveCardUrl); `note` records have no
2359
2368
  // public URL and render non-clickable. So no app-level pattern applies.
2360
2369
  },
2370
+ guestbook: {
2371
+ // Guestbook (dev.baileytownsend.guestbook) is a self-hosted, cross-site
2372
+ // widget: each site owner renders their own guestbook wherever they choose,
2373
+ // so there is no canonical public per-entry viewer or per-handle profile
2374
+ // page. Entries render non-clickable. Same shape as crate `note`.
2375
+ },
2361
2376
  atmorsvp: {
2362
2377
  // atmo.rsvp events live at /p/{did}/e/{rkey}. The per-item pattern is used
2363
2378
  // for the event record itself; checkin records build their URL from the
@@ -2468,7 +2483,11 @@ var COLLECTION_TO_APP = [
2468
2483
  ["os.aether.", "aetherdocs"],
2469
2484
  ["io.kich.recipe.recipe", "kich"],
2470
2485
  // Onboard from moll.dev profile audit.
2471
- ["exchange.recipe.recipe", "recipe"]
2486
+ ["exchange.recipe.recipe", "recipe"],
2487
+ // Onboard from willow.sh profile audit.
2488
+ ["dev.baileytownsend.guestbook.", "guestbook"],
2489
+ // Onboard from trezy.codes profile audit.
2490
+ ["app.atmobb.", "atmobb"]
2472
2491
  ];
2473
2492
 
2474
2493
  // src/cards/resolve-card-url.ts
@@ -2589,6 +2608,26 @@ function resolveCardHealth(item) {
2589
2608
  }
2590
2609
  return { url: null, strategy: "none" };
2591
2610
  }
2611
+ if (collection === "app.atmobb.discussion.reply") {
2612
+ const thread = record.thread;
2613
+ if (thread != null && typeof thread === "object") {
2614
+ const threadUri = stringOrNull(thread.uri);
2615
+ if (threadUri) {
2616
+ const parsed3 = parseAtUri(threadUri);
2617
+ if (parsed3) {
2618
+ return urlHealth(`https://atmobb.app/t/${parsed3.did}/${parsed3.rkey}`);
2619
+ }
2620
+ }
2621
+ }
2622
+ return { url: null, strategy: "none" };
2623
+ }
2624
+ if (collection === "app.atmobb.discussion.thread") {
2625
+ const parsed3 = parseAtUri(uri);
2626
+ if (parsed3) {
2627
+ return recordHealth(`https://atmobb.app/t/${parsed3.did}/${parsed3.rkey}`);
2628
+ }
2629
+ return { url: null, strategy: "none" };
2630
+ }
2592
2631
  if (collection === "fyi.atstore.listing.review") {
2593
2632
  const listingMeta = record.listingMeta;
2594
2633
  if (listingMeta != null && typeof listingMeta === "object") {
@@ -3243,10 +3282,18 @@ function bskyImages(embed, did) {
3243
3282
  for (const raw of images) {
3244
3283
  const img = asRecord(raw);
3245
3284
  if (!img) continue;
3285
+ const alt = asNonEmptyString(img.alt) ?? "";
3286
+ const ratio = aspectRatio(img.aspectRatio);
3287
+ const resolvedUrl = asNonEmptyString(img.thumb) ?? asNonEmptyString(img.fullsize);
3288
+ if (resolvedUrl) {
3289
+ const media2 = { url: resolvedUrl, alt };
3290
+ if (ratio) media2.aspectRatio = ratio;
3291
+ out.push(media2);
3292
+ continue;
3293
+ }
3246
3294
  const cid = blobCid(img.image);
3247
3295
  if (!cid) continue;
3248
- const media = { did, cid, alt: asNonEmptyString(img.alt) ?? "" };
3249
- const ratio = aspectRatio(img.aspectRatio);
3296
+ const media = { did, cid, alt };
3250
3297
  if (ratio) media.aspectRatio = ratio;
3251
3298
  const mimeType = asNonEmptyString(asRecord(img.image)?.mimeType);
3252
3299
  if (mimeType) media.mimeType = mimeType;
@@ -3262,13 +3309,16 @@ function bskyExternal(embed) {
3262
3309
  const link2 = { url };
3263
3310
  const title = asNonEmptyString(external.title);
3264
3311
  if (title) link2.title = title;
3312
+ const thumb = asNonEmptyString(external.thumb);
3313
+ if (thumb) link2.thumb = thumb;
3265
3314
  return link2;
3266
3315
  }
3267
3316
  function bskyEmbedContent(record, did) {
3268
3317
  const embed = asRecord(record.embed);
3269
3318
  if (!embed) return {};
3270
3319
  const type = asNonEmptyString(embed["$type"]);
3271
- const target = type === "app.bsky.embed.recordWithMedia" ? asRecord(embed.media) : embed;
3320
+ const isRecordWithMedia = type === "app.bsky.embed.recordWithMedia" || type === "app.bsky.embed.recordWithMedia#view";
3321
+ const target = isRecordWithMedia ? asRecord(embed.media) : embed;
3272
3322
  if (!target) return {};
3273
3323
  if (Array.isArray(target.images)) {
3274
3324
  const media = bskyImages(target, did);
@@ -4643,7 +4693,7 @@ var ProfileVolunteeringRecordSchema = zod.z.object({
4643
4693
  });
4644
4694
 
4645
4695
  // src/index.ts
4646
- var SIFA_SDK_VERSION = "0.12.24";
4696
+ var SIFA_SDK_VERSION = "0.12.27";
4647
4697
 
4648
4698
  exports.ACTIVITY_TIERS = ACTIVITY_TIERS;
4649
4699
  exports.ACTIVITY_VERBS = ACTIVITY_VERBS;